如何在没有 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**2Out[4]:Index 0.000076SAMAC 11126.227417SAMAC.1 11126.227417REG 10484.106445Value 1397.880859 恐怕它不起作用,因为出现“内存错误”。

以上是关于如何在没有 MemoryError 的情况下将 183,223,040x4 矩阵重塑为 140 个尺寸为 1145x1145 的矩阵?的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar?

如何在没有副本的情况下将结构转换为字节数组?

如何在没有 foreach 的情况下将项目从列表复制到列表?

如何在没有 Geofire 的情况下将位置对象保存在 Firebase 中?

如何在没有数据库的情况下将数据保存到数组中

如何在没有问题的情况下将角半径应用于 UIView?