一次处理一列,而不是将整个数据保存在 python 中的内存中



我在 redshift 中有一个大型数据集(~ 300 万行和 1500 列(。目前我正在提取所有数据并进行一些数据处理,例如 缺失价值插补和创建假人等。我通过循环访问列名来对每一列执行此操作。这会消耗大量内存,因为 数据大小,因为我将整个数据保存在数据帧中,直到处理完成。

我正在考虑将数据存储在csv中,然后在每列中读取,进行数据处理并将处理后的列写入csv。

数据

sv_m1   rev     ioip    dvr_m1  geo
0       15.31   40      0       NJN
0       64.9    0       0       CT
0       18.36   20      0       AX
0       62.85   0       0       AL
0       10.31   20      0       BS
0       12.84   10      13.95   MN
0       69.95   0       0       CT
0       32.81   20      13.95   FX

所以说我的csv拥有所有数据是:seg_data.csv

我想阅读第一列,进行处理并将其写入另一个csv - final_seg.csv。 然后我想对下一列和下一列执行相同的操作,并且对所有列执行类似的操作。 如果变量像 geo 一样是分类的,则数据处理可能涉及创建假人。 我在单独的 csv 中维护变量名称和类型的映射,并将其加载到 dict (attribute_dict( 中。

以下是我从数据库读取数据并将其存储在df_data_sample中后当前正在做的事情。

df_final = pd.DataFrame()
for column in df_data_sample.columns:
df_column = df_data_sample[[column]]
if (((attribute_dict[column] == 'CAT') & (df_column[column].unique().size < 100))==True):
df_target_attribute = pd.get_dummies(df_column[column], dummy_na=True, prefix=column)
df_target_attribute.fillna(0) 
df_final[target_column] = df_target_attribute[[target_column]]

elif (attribute_dict[column] == 'NUM'):
#Let's impute with 0 for numeric variables:
df_target_attribute = df_column
df_target_attribute.fillna(value=0,inplace=True)
df_final[column] = df_target_attribute

所以基本上我不想df_data_sample保存在内存中,一次只加载一列,处理它,写入处理后的列(如果是数字(, 和列(如果分类为假人(到另一个 CSV 中。这应该对所有列发生。

预期输出 csv

sv_m1   rev     ioip    dvr_m1  geo_NJN geo_CT  geo_AX geo_BS   
0       15.31   40      0       1       0       0       0
0       64.9    0       0       0       1       0       0
0       18.36   20      0       0       0       1       0
0       62.85   0       0       1       0       0       0
0       10.31   20      0       0       0       0       1
0       12.84   10      13.95   0       0       1       0
0       69.95   0       0       0       1       0       0
0       32.81   20      13.95   0       0       0       1

我在想,由于我一次只在内存中保留 1 列,这将减少我的内存使用量(目前在服务器上达到 75%(。

有人可以帮我吗?

read_csv中的usecols参数将帮助您实现此目的。我这样做的方式是我会一遍又一遍地加载数据的子集 -

cols = ["sv_m1","rev","ioip","dvr_m1","geo_NJN","geo_CT","geo_AX","geo_BS"]
for col in cols:
df = pd.read_csv('sample.csv', usecols=[col])
print(df)

而不是print(df),显然你会用那一列进行处理。

您可以使用if/else来满足不同列的不同处理。

希望有帮助。

读取 CSV 文件很慢,如果原始数据来自 CSV 文件,则可以读取 Cuck 中的 CSV 文件,并使用to_hdf(..., append=True)将其附加到 HDF5 文件中。然后按pd.read_hdf(..., columns=[...])阅读该列。

最新更新