在 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()
函数来获取其各个元素并逐个处理它们。
我想在 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()
函数来获取其各个元素并逐个处理它们。