我正在寻找一种比pd.concat更有效的方法来组合两个熊猫DataFrame。
我有一个大型DataFrame(大小约为7GB),其中包含以下各列-“ A”,“ B”,“ C”,“ D”。我想按“ A”对框架进行分组,然后针对每个组: 按“ B”分组,对“ C”取平均值,对“ D”求和,然后将所有结果组合到一个数据帧中。我尝试了以下方法-
1)创建一个空的最终DataFrame,迭代“ A”的groupby进行我需要的处理,然后pd.concat每个组都将最终DataFrame。问题是pd.concat非常慢。
2)遍历“ A”的分组依据,进行我需要的处理,然后将结果保存到csv文件中。可以,但是我想找出是否有一种更有效的方法,不涉及写入磁盘的所有I / O。
代码示例
第一种方法-带有pd.concat的最终DataFrame:
def pivot_frame(in_df_path):
in_df = pd.read_csv(in_df_path, delimiter=DELIMITER)
res_cols = in_df.columns.tolist()
res = pd.DataFrame(columns=res_cols)
g = in_df.groupby(by=["A"])
for title, group in g:
temp = group.groupby(by=["B"]).agg({"C": np.mean, "D": np.sum})
temp = temp.reset_index()
temp.insert(0, "A", title)
res = pd.concat([res, temp], ignore_index=True)
temp.to_csv(f, mode='a', header=False, sep=DELIMITER)
return res
第二种方法-写入磁盘:
def pivot_frame(in_df_path, ouput_path):
in_df = pd.read_csv(in_df_path, delimiter=DELIMITER)
with open(ouput_path, 'w') as f:
csv_writer = csv.writer(f, delimiter=DELIMITER)
csv_writer.writerow(["A", "B", "C", "D"])
g = in_df.groupby(by=["A"])
for title, group in g:
temp = group.groupby(by=["B"]).agg({"C": np.mean, "D": np.sum})
temp = temp.reset_index()
temp.insert(0, JOB_TITLE_COL, title)
temp.to_csv(f, mode='a', header=False, sep=DELIMITER)
第二种方法的工作方式比第一种方法快,但是我正在寻找可以使我一直无休无止地访问磁盘的东西。我读到有关“拆分应用组合”(例如-https://pandas.pydata.org/pandas-docs/stable/user_guide/groupby.html)的信息,但没有发现有帮助。
非常感谢! :)
答案 0 :(得分:1)
已解决
Niels Henkens的评论确实有帮助,解决方案是-
result = in_df.groupby(by=["A","B"]).agg({"C": np.mean, "D": np.sum})
性能的另一项改进是使用Dask-
import dask.dataframe as dd
df = dd.read_csv(PATH_TO_FILE, delimiter=DELIMITER)
g = df.groupby(by=["A", "B"]).agg({"C": np.mean, "D": np.sum}).compute().reset_index()