python - 如何在没有 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 天)。有没有办法加快这个速度?
解决方案
更新1:在了解了OP由于数据框大而导致计算缓慢的问题后,这里是更新。
使用以下方法检查列的 dtypes
all_sam.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
希望这将实现更快的计算。
参考:向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)
推荐阅读
- android - 如何在不创建新应用的情况下从生产中取消发布应用并在 Google Play 中重新发布测试版?
- symfony - Symfony - 无法识别树枝中的 js 脚本
- python-3.x - 为什么我尝试在 selenium python 中循环遍历 href 时出错?
- ios - Swift:将数据从 tableView 显示到另一个 ViewController(JSON、Alamorife、AlamofireImage)
- json - 在 Spring Boot 应用程序中将数据存储到数据库的问题
- java - 解决eclipse中的maven依赖类
- javascript - 使用 angularjs 更新表数据而不使用后端
- c# - 如何将字符串列表从 Sql 数据插入 Document Db / cosmos db?
- python - 基于 pandas df 中不同值的累积计数
- android - 在 onMapReady 内部,毕加索第一次没有加载图像