Pandas -如何根据条件合并行

4xrmg8kj  于 2023-04-28  发布在  其他
关注(0)|答案(1)|浏览(120)

我有一个Pandas dataframe,其中有数千行,我想合并为更少的行。
在新的dataframe中,我想要:

  • 某些列是分组行的总和
  • 某些列是分组行的平均值,并且
  • 一些其他列是相同列的加权平均,其中权重因子是另一列(在原始 Dataframe 中)。

我的搜索显示我可能会使用agg函数来实现上面的部分(不太确定)。但最难的部分是用Pandas编写条件,选择需要合并的行数。下面是一个例子:

df = pd.DataFrame({'col1': [1, 1, 2, 2, 3, 4, 2],
                   'col2': [10, 20, 30, 40, 50, 60, 70],
                   'col3': [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7],
                   'col4': [2, 1, 4, 5, 8, 10, 3]})

我对要合并的行数的判断标准是,第1列的值之和要高于某个阈值。假设这里是3:

  • 行1、2和3被分组(总和为4〉3)。
  • 第4行和第5行被分组在一起(总和是5〉3)
  • 行6将不被分组(4〉3),在新的 Dataframe 中保持相同。
  • 行7将不被分组,因为不存在其它行,在新 Dataframe 中保持相同。

最终的dataframe看起来像这样:

第1列和第2列是分组行的总和。第3列是分组行的平均值。第3列是权重因子为第1列的分组行的加权平均值。

newdf = pd.DataFrame({'col1': [4, 5, 4, 2],
                   'col2': [60, 90, 60, 70],
                   'col3': [0.2, 0.45, 0.6, 0.7],
                   'col4': [2.75, 6.8, 10, 3]})

有人能帮帮我吗
我看了一下这个问题,但仍然有两个问题:分组标准不起作用,并且不确定加权平均值如何

agg_funcs = {'col1': 'sum', 'col2': 'sum','col3': 'mean', 'col4': lambda x: (x['col1'] * x['col4']).sum() / x['col1'].sum()}

grouped_df = df.groupby('col1').agg(agg_funcs)

代码失败,抱怨加权平均块,但分组标准也不正确!

rkkpypqq

rkkpypqq1#

你需要改变两件事:

  • 对值进行分组的方式:你不能用向量的方式按累积值分组,直到达到阈值。你需要一个循环。
  • 计算加权平均值的方法不能用于aggagg只能按列/系列计算,而不知道其他列。但是,您可以预先计算权重sum,然后除以权重之和。
def threshold_grouper(s, thresh=3):
    group = []
    i = 0
    total = 0
    for val in s:
        total += val
        group.append(i)
        if total>=thresh:
            i+=1
            total=0
    return group

(df.eval('col4 = col4*col1')
   .groupby(threshold_grouper(df['col1']))
   .agg({'col1': 'sum', 'col2': 'sum', 'col3': 'mean', 'col4': 'sum'})
   .eval('col4 = col4/col1')
)

你也可以在agg中作弊并使用一个副作用,从外部访问“col 1”:

(df.groupby(threshold_grouper(df['col1']))
   .agg({'col1': 'sum', 'col2': 'sum', 'col3': 'mean',
         'col4': lambda g: np.average(g, weights=df['col1'].reindex_like(g))})
)

输出:

col1  col2  col3   col4
0     4    60  0.20   2.75
1     5    90  0.45   6.80
2     4    60  0.60  10.00
3     2    70  0.70   3.00

相关问题