5

如何在数据框函数内的 lambda 函数中使用三元运算applypandas

首先,这段代码来自 R/plyr,这正是我想要得到的:

ddply(mtcars, .(cyl), summarise, sum(ifelse(carb==4,1,0))/sum(ifelse(carb %in% c(4,1),1,0)))

在上述函数中,我可以使用ifelse函数 R 的三元运算符来计算结果数据帧。

但是,当我想使用以下代码在 Python/pandas 中执行相同操作时

mtcars.groupby(["cyl"]).apply(lambda x: sum(1 if x["carb"] == 4 else 0) / sum(1 if x["carb"] in (4, 1) else 0))

,出现以下错误:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

那么如何计算并获得与 R/plyr 中相同的数据帧?

供您参考,如果我使用三元运算符而不对列进行分组,例如

mtcars.apply(lambda x: sum(1 if x["carb"] == 4 else 0) / sum(1 if x["carb"] in (4, 1) else 0), axis=1)

,由于某些原因,我可以获得结果数据框(但这不是我想要做的)。

谢谢。

[更新]

抱歉,在使用三元运算符时,原始示例不是一个好示例,因为它使用1and 0,它可以用作二进制。所以更新的 R/plyr 代码如下:

ddply(mtcars, .(cyl), summarise, sum(ifelse(carb==4,6,3))/sum(ifelse(carb %in% c(4,1),8,4)))

在这种情况下使用三元运算符是否可行?

4

3 回答 3

4

我认为您的代码可以翻译成这样:

mtcars.groupby(["cyl"])['carb'].apply(lambda x: sum((x == 4).astype(float)) / sum(x.isin((4, 1))))

玩具示例:

>>> mtcars = pd.DataFrame({'cyl':[8,8,6,6,6,4], 'carb':[4,3,1,5,4,1]})
>>> mtcars
   carb  cyl
0     4    8
1     3    8
2     1    6
3     5    6
4     4    6
5     1    4
>>> mtcars.groupby(["cyl"])['carb'].apply(lambda x: sum((x == 4).astype(float)) / sum(x.isin((4, 1))))
cyl
4      0.0
6      0.5
8      1.0
dtype: float64

更新

在更复杂的情况下,您可以使用numpy.where()函数:

>>> import numpy as np
>>> mtcars.groupby(["cyl"])['carb'].apply(lambda x: sum(np.where(x == 4,6,3).astype(float)) / sum(np.where(x.isin((4,1)),8,4)))
cyl
4      0.375
6      0.600
8      0.750
dtype: float64
于 2013-11-15T04:54:35.880 回答
2

在我看来,它x['carb']是一个 numpy 数组(或子类)。在这种情况下,x['carb'] == 4返回一个布尔数组。 True其中值等于 4,False否则。这是 numpy 的一个非常方便的功能,但在这种情况下可能会很烦人(因为期望==运算符返回布尔结果是很自然的)。

诀窍是调用.all()结果:

(x['carb'] == 4).all()

True只有当所有元素(x['carb'] == 4)都是时才会返回True

于 2013-11-15T04:32:30.823 回答
0

Pandasapply()适用于行。因此,三元运算符可以用作

df.apply(lambda row: [1 if x>0 else 0 for x in row])

在 OP 的例子中:

mtcars.groupby(["cyl"])['carb'].apply(lambda r: sum([1 if x==4 else 0 for x in r])/sum([1 if x in [1,4] else 0 for x in r]))

(这个例子可能需要捕捉除以零,虽然......)

于 2021-08-02T16:49:52.640 回答