Python 在groupby之后基于条件数据帧应用函数
我想在groupby之后对一组数字执行一个函数,但该函数仅在满足特定条件时才起作用。有没有办法执行两种不同的操作 假设我们想在groupby之后应用函数1/x。对于x==0,当然不能这样做,但我们只希望得到0作为返回值。通常情况下,这看起来像这样Python 在groupby之后基于条件数据帧应用函数,python,pandas,conditional-statements,pandas-groupby,pandas-apply,Python,Pandas,Conditional Statements,Pandas Groupby,Pandas Apply,我想在groupby之后对一组数字执行一个函数,但该函数仅在满足特定条件时才起作用。有没有办法执行两种不同的操作 假设我们想在groupby之后应用函数1/x。对于x==0,当然不能这样做,但我们只希望得到0作为返回值。通常情况下,这看起来像这样 如果x>0:返回1/x否则:返回0 但是, df.groupby(by=[“index”])。应用(如果x==0,则lambda x:0,否则为1/x) 给我一条错误消息: ValueError:序列的真值不明确。使用a.empty、a.bool()、
如果x>0:返回1/x否则:返回0
但是,
df.groupby(by=[“index”])。应用(如果x==0,则lambda x:0,否则为1/x)
给我一条错误消息:
ValueError:序列的真值不明确。使用a.empty、a.bool()、a.item()、a.any()或a.all()
构建的数据如下所示:
经过一次群比之后,我只剩下
df=
|索引|值1|
| --- | -----|
|a | 0|
|b | 0.5|
|c | 0.2 |,
其中索引不再可调用
我还有数据集
危险品=
指数
价值2
价值3
A.
1.
5.
A.
2.
8.
C
3.
7.
C
7.
7.
B
5.
6.
B
7.
13
您可以创建一个函数来执行此操作:-
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 = 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()
函数获取其单个元素,并按元素处理它们。如果您的问题中包含一个示例输入/输出数据帧,这将非常有用。您得到了什么错误我得到的错误是:ValueError:序列的真值不明确。使用a.empty、a.bool()、a.item()、a.any()或a.all()。
谢谢,这似乎适用于单个列。有没有办法把它扩展到两列,其中条件基于一列?是的,你的条件是什么?我说我有a列和b列。然后我想做一些类似于.apply(如果x.b=0,则lamda x:0,否则x.a.sum()/x.b)
的事情,你能发布你的df输出吗?比如打印(df)
的输出,或者你的数据框看起来怎么样,或者发布你的数据框的一小部分。谢谢你的帮助和耐心!但是,如果每行都有几列需要计算,那么x.to_list()将生成一个嵌套列表。然后,我不能再使用y.value1,但必须使用y[0]例如?@Mick_99您在开始时没有提到这样的跨列操作要求,并在发布了多个答案后对问题进行了重大更改。请注意在将来一次过写清楚你的要求。我理解你的意思。我得到了一些反馈,所以我改变了它!
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