熊猫:组合数据框的有效方法

时间:2019-04-27 06:54:14

标签: python pandas performance split-apply-combine

我正在寻找一种比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)的信息,但没有发现有帮助。

非常感谢! :)

1 个答案:

答案 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()