如何在没有 MemoryError 的情况下将 183,223,040x4 矩阵重塑为 140 个尺寸为 1145x1145 的矩阵?
Posted
技术标签:
【中文标题】如何在没有 MemoryError 的情况下将 183,223,040x4 矩阵重塑为 140 个尺寸为 1145x1145 的矩阵?【英文标题】:How to reshape a 183,223,040x4 matrix into 140 matrices of dimensions 1145x1145 without MemoryError? 【发布时间】:2019-08-15 14:52:52 【问题描述】:我有一个尺寸为 183,223,040x4 的矩阵,其变量如下所示。 'REG'有140个不同的值,'SAMAC'和'SAMAC.1'都有1145个不同的值
我想遍历 REG 以获得 140 个大小为 1145*1145 的矩阵,其中包含正确的“值”。
我尝试了以下方法:
-循环国家
-创建空矩阵 1145*1145,以 SAMAC 为索引,列名称为 SAMAC.1
-逐行查看当前数据帧
-检查 SAMAC(行)和 SAMAC.1(列)的值
-在空矩阵中定位 SAMAC 和 SAMAC.1 并分配相应的 VALUE
import pandas as pd
import dask.dataframe as dd
all_sam=dd.read_csv(r'C:\GP2\all_sams_trial.csv',skiprows=1)
all_sam.head()
SAMAC SAMAC.1 REG Value
0 m_pdr m_pdr aus 0.0
1 m_wht m_pdr aus 0.0
2 m_gro m_pdr aus 0.0
3 m_v_f m_pdr aus 0.0
4 m_osd m_pdr aus 0.0
countries=list(all_sam["REG"].unique().compute())
col_names=list(all_sam["SAMAC"].unique().compute())
for country in countries:
df=pd.DataFrame(0,index=col_names,columns=col_names)
sam=all_sam[all_sam["REG"]==country].compute()
for index,row in sam.iterrows():
row_index=str(row["SAMAC"])
col_index=str(row["SAMAC.1"])
df.loc[row_index,col_index]=row['Value']
print(index)
df.to_csv(country+"_SAM.csv")
问题在于计算需要很长时间(大约 2 天)。有没有办法加快速度?
【问题讨论】:
【参考方案1】:更新一:了解了OP由于dataframe大而导致计算缓慢的问题,下面是更新。
使用 all_sam.dtypes
检查列的 dtypes 和数据框的大小(以 Mb 为单位):
all_sam.memory_usage(deep=True) / 1024 ** 2
考虑将列名“SAMAC.1”更改为“SAMAC_1”,因为这可能会导致以下行出错。在处理之前将“REG”、“SAMAC”和“SAMAC_1”的数据类型更改为“分类”:
all_sam.REG = all_sam.REG.astype('category')
all_sam.SAMAC = all_sam.SAMAC.astype('category')
all_sam.SAMAC_1 = all_sam.SAMAC_1.astype('category')
根据您的要求,您可以使用以下代码将“Value”列的 dtype 向下转换为 float16、int16、int8 等:
all_sam.Value = all_sam.Value.astype('float16')
再次检查尺寸。
all_sam.memory_usage(deep=True) / 1024 ** 2
希望这将使计算速度更快。
参考:towardsdatascience.com
我采用了一个小的示例数据框来解决您的问题。
import pandas as pd
import numpy as np
df = pd.DataFrame( 'REG':['A','A','A','A','A','A','B','B','B','B','B','B'], 'SAMAC1':['a','a','a','b','b','b','c','c','c','d','d','d'], 'SAMAC':['p','q','r','p','q','r','p','q','r','p','q','r'], 'value':[0,0,0,0,0,0,0,0,0,0,0,0])
array_ = df[['REG','SAMAC1','SAMAC']].values.transpose()
index = pd.MultiIndex.from_arrays(array_, names=('REG', 'SAMAC1','SAMAC'))
df2 = df['value']
df2.index=index
country_labels = df2.index.get_level_values(0)
country_unique = country_labels.unique()
result_arr = []
for c in country_unique:
df3 = df2[df2.index.get_level_values(0) == c]
result_arr.append(df3.unstack().values)
result_arr = np.array(result_arr)
print(result_arr.shape)
输出:(2,2,3)
【讨论】:
非常感谢@jatin!然而,时间问题似乎仍然存在。每个步骤都需要很长时间(只需运行 array_ = df[['REG','SAMAC1','SAMAC']].values.transpose() 大约需要 12 分钟)。这是因为初始矩阵很大 您介意分享您的计算机规格吗?谢谢:) 你能运行这个命令来显示你的数据框的存储内存使用情况吗? all_sam.memory_usage(deep=True)/ 1024 ** 2 用 pandas 加载数据帧大约需要 10 分钟。我的电脑还可以(8GB RAM,Intel I5-5th generation)。从中加载数据的 csv 重量为 4.4GB,一旦加载数据框:all_sam.memory_usage(deep=True)/1024**2
Out[4]:
Index 0.000076
SAMAC 11126.227417
SAMAC.1 11126.227417
REG 10484.106445
Value 1397.880859
恐怕它不起作用,因为出现“内存错误”。以上是关于如何在没有 MemoryError 的情况下将 183,223,040x4 矩阵重塑为 140 个尺寸为 1145x1145 的矩阵?的主要内容,如果未能解决你的问题,请参考以下文章
如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar?
如何在没有 foreach 的情况下将项目从列表复制到列表?