我有一个大熊猫df(百万行x数千列),由于dtypes导致内存问题。我已经编写了代码来扫描数据,并通过分别解析每个列来以最佳dtypes编码数据,但是运行大约需要24个小时。该工作需要占用大量RAM,但通常不会使用1个以上的内核,因此我想通过并行化来优化以利用更多的内核并加速任务。
我尝试在python中使用多处理库(下面的代码),但是所获得的收益并不是巨大的。我也研究了一下dask,但不确定是否可行。节省空间最大的项目之一是object-> categorical,所以我认为我需要一整篇文章才能使它起作用。我知道我可以在输入时指定分类dtype,但是我正在读取许多文件(多年),因此,只要一级更改,它就会返回对象。
import pandas as pd
from multiprocessing.dummy import Pool as ThreadPool
def combine_n_clean(col):
appended_df = []
for calyear in range(start_yr,end_yr):
df = pd.read_feather('dataloc.feather', columns = [col])
appended_df.append(df)
appended_df = pd.concat(appended_df, axis = 0, ignore_index = True)
appended_df = float_to_cat_conversion(appended_df) #Float32 -> Integer or Categorical
appended_df = object_var_conversion(appended_df) #Object -> Categorical
return appended_df
def object_var_conversion(df_name):
object_df = df_name.select_dtypes(include=['object'])
converted_obj = pd.DataFrame()
for col in object_df.columns:
num_unique_values = len(object_df[col].unique())
num_total_values = len(object_df[col])
if num_unique_values / num_total_values < 0.5: #Only convert to Category if under 50% unique var
converted_obj.loc[:,col] = object_df[col].astype('category')
else:
converted_obj.loc[:,col] = object_df[col]
del object_df
df_name = df_name.drop(columns=converted_obj.columns) #Drop object columns
df_name = pd.concat([df_name,converted_obj], axis = 1) #Add back in categorical columns
del converted_obj
return df_name
pool = ThreadPool(16)
results = pool.map(combine_n_clean, col_name_list)
pool.close()
pool.join()
results = pd.concat(results, axis=1)
上面的代码可以运行,但是基本上没有节省时间。