在 groupby 之后应用基于条件数据框的函数

Applying function based on a condtion dataframe after groupby

我想在 groupby 之后对一组数字执行一个函数,但是这个函数只有在满足特定条件时才有效。有没有办法执行两种不同的操作?

假设我们想在 groupby 之后应用函数 1/x。这对于 x==0 来说当然是做不到的,但是我们只想得到 0 作为 return 的值。通常,这看起来像这样

if x > 0: return 1/x else: return 0

然而,做

df.groupby(by = ["index"]).apply(lambda x: 0 if x == 0 else 1/x)

给我一条错误信息: ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

构造的数据如下:

分组后,我剩下

df = |索引|值1| | --- | ------| |一个 |0 | |乙 | 0.5| | c | 0.2|, 其中索引不再可调用。

我也有数据集

dg =

index value2 value3
a 1 5
a 2 8
c 3 7
c 7 7
b 5 6
b 7 13

我加入指数使用

dh = pd.merge(dg, df, how = 'left', on = index)`.

现在我想应用这个功能

dh.groupby(by=index).apply(lambda x: (((x.value2/x.value3) - x.value1)**2).sum() / (x.value1 * (x.n.count())),

当value1为0时显然不能执行。如前所述放入条件会给我上述错误。我该怎么办?

您可以创建一个函数来为您执行此操作:-

def func(x):
    if x['value1'].gt(0).all():
        return 1/x['value1']
    else:
        return ((((x['value2']/x['value3'])-x['value1'])**2).sum()/x['value1']*x['value1'].count())

现在只需使用:-

dh.groupby(by = ["index"]).apply(func)

输出:-

index   
a      0    inf
       1    inf
b      4    2.0
       5    2.0
c      2    5.0
       3    5.0

尝试:

df.groupby(by = ["index"]).transform(lambda x: [0 if y == 0 else 1/y for y in x.to_list()])

这适用于多列:

df = pd.DataFrame({'index': [0, 0, 0, 1, 1, 1], 'A':[0,1,2,3,4, 5], 'B':[50, 40,30,20,10, 0]})

print(df)

   index  A   B
0      0  0  50
1      0  1  40
2      0  2  30
3      1  3  20
4      1  4  10
5      1  5   0

df.groupby(by = ["index"]).transform(lambda x: [0 if y == 0 else 1/y for y in x.to_list()])

Output:

          A         B
0  0.000000  0.020000
1  1.000000  0.025000
2  0.500000  0.033333
3  0.333333  0.050000
4  0.250000  0.100000
5  0.200000  0.000000

说明

由于 groupby.apply() 是通过数据帧传递的,因此 lambda x 中的 x 实际上是基于组的数据帧的一部分。因此,文本 x == 0 正在将数据帧与 0 进行比较并给出错误。

对于groupby.transform(),它通过系列而不是数据帧传递。因此,我们可以使用 Series.to_list() 函数来获取其各个元素并逐个处理它们。