首页 > 解决方案 > 如何在没有 MemoryError 的情况下将 183,223,040x4 矩阵重塑为 140 个尺寸为 1145x1145 的矩阵?

问题描述

我有一个尺寸为 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 天)。有没有办法加快这个速度?

标签: pythonpandasdataframememorylarge-data

解决方案


更新1:在了解了OP由于数据框大而导致计算缓慢的问题后,这里是更新。

  1. 使用以下方法检查列的 dtypesall_sam.dtypes和数据框的大小(以 Mb 为单位):

    all_sam.memory_usage(deep=True) / 1024 ** 2
    
  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')
    
  3. 根据您的要求,您可以使用以下代码将“Value”列的 dtype 向下转换为 float16、int16、int8 等:

    all_sam.Value = all_sam.Value.astype('float16')
    
  4. 再次检查尺寸。

    all_sam.memory_usage(deep=True) / 1024 ** 2
    

希望这将实现更快的计算。

参考:向datascience.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)


推荐阅读