首页 > 解决方案 > 基于公共列合并 Pandas 数据框中的行,同时附加一些字段

问题描述

如果这是一个非常基本的问题,请原谅我是 Python 和 Pandas 的相对初学者。

我有一个观察和分类的 csv 文件。每个观察结果在结果中出现多次,因为使用不同的训练数据重复分类,由“split_on”列指示。我希望将同一观察的所有实例合并到一行中,同时保留不同的分类结果,并另外添加平均列。

这是原始形式中单个观察的样子:

约会时间 出价 数据1 数据2 数据3 分裂开 可能性 预言
50:03.3 WI172 123 456 789 组1 0.2 第一类
50:03.3 WI172 123 456 789 组2 0.4 第一类
50:03.3 WI172 123 456 789 组3 0.7 类2
50:03.3 WI172 123 456 789 第 4 组 0.2 第一类

这是合并后的样子:

约会时间 出价 数据1 数据2 数据3 group1_prob group2_prob group3_prob group4_prob group1_pred group2_pred group3_pred group4_pred 概率平均 预测平均值
50:03.3 WI172 123 456 789 0.2 0.4 0.7 0.2 第一类 第一类 类2 第一类 0.375 第一类

有几个注意事项:

我写了以下内容来实现这一点:

import pandas as pd

group_cols = ["datetime", "bID"] #this is enough to uniquely identify a single observation

groups = set()

chunksize = 10 ** 6
#first pass over file collects a list of groups
for chunk in pd.read_csv("result.csv",
                         chunksize=chunksize, usecols=group_cols):
    chunkGroups = chunk.groupby(group_cols)

    for (groupLevels), chunkGroup in chunkGroups:
        groups.add(groupLevels)

rows = []
#now pass over file for each group to collect associated rows
for group in groups:
    result = []
    for chunk in pd.read_csv("result.csv", chunksize=chunksize):
        chunkGroups = chunk.groupby(group_cols)
        if group in chunkGroups.groups.keys():
            result.append(chunkGroups.get_group(group))

    result_df = pd.concat(result) #This dataframe contains all rows pertaining to a single observation

    result_df.set_index('split_on', inplace=True)

    probs=result_df['probability']
    probs.index += "_prob"
    preds=result_df['prediction']
    preds.index += "_pred"

    new_row = pd.Series(result_df.iloc[0].drop(['probability','prediction']))
    new_row = pd.concat([new_row,probs,preds])

#add a class label based on the average probability
    new_row['probability-avg'] = result_df['probability'].mean()
    if new_row['probability-avg'] > 0.5:
        new_row['predictedAspect-avg'] = "class2"
    else:
        new_row['predictedAspect-avg'] = "class1"

    rows.append(new_row)
    print('merged row: ', new_row)

rows_df = pd.concat(rows, axis=1,sort=True).transpose()

rows_df.to_csv("mergedResults.csv", index=False)

这可行,但转换速度非常慢(每行几秒钟!),并且像这样处理我的整个文件将花费比我更多的时间。

有没有更明智的方法来实现这一目标?

标签: pythonpandasdataframe

解决方案


使用pivot

from statistics import mode

k = df.pivot(index=['datetime', 'bID', 'data1', 'data2', 'data3'], columns=[
             'split_on'], values=['probability', 'prediction'])
k.columns = k.columns.map(lambda x: '_'.join(x[::-1]))

df = k.reset_index()

df['prediction_avg'] = df.filter(regex=r'.*_prediction').mode(1)
df['probability_avg'] = df.filter(regex=r'.*_probability').mean(1)

输出:

约会时间 出价 数据1 数据2 数据3 group1_probability group2_probability group3_probability group4_probability group1_prediction group2_prediction group3_prediction group4_prediction 预测平均 概率平均值
50:03.3 WI172 123 456 789 0.2 0.4 0.7 0.2 第一类 第一类 类2 第一类 第一类 0.375

推荐阅读