我在 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=[...])
阅读该列。