在分组的大熊猫 df 中使用 IF-THEN 创建新列



我正在将一个简单的函数应用于分组的熊猫df。以下是我正在尝试的。即使我尝试修改函数以执行一个步骤,我也不断收到相同的错误。任何方向都会超级有帮助。

def udf_pd(df_group):
if (df_group['A'] - df_group['B']) > 1:
df_group['D'] = 'Condition-1'
elif df_group.A == df_group.C:
df_group['D'] = 'Condition-2'
else:
df_group['D'] = 'Condition-3'
return df_group
final_df = df.groupby(['id1','id2']).apply(udf_pd)
final_df = final_df.reset_index()

ValueError: The truth value of a Series is ambiguous. Use a.empty, 
a.bool(), a.item(), a.any() or a.all().

请注意,在groupby.apply中,该函数将应用于整个组。 另一方面,每个if条件必须归结为单个值 (不适用于任何真/假系列)。

因此,此函数中 2 列的每个比较都必须补充 例如all()any(),如下例所示:

def udf_pd(df_group):
if (df_group.A - df_group.B > 1).all():
df_group['D'] = 'Condition-1'
elif (df_group.A == df_group.C).all():
df_group['D'] = 'Condition-2'
else:
df_group['D'] = 'Condition-3'
return df_group

当然,该函数可以返回整个组,例如"extended" 通过新列,在这种情况下,新列的单个值 是广播,因此当前组中的每一行都接收此值。

我创建了一个测试数据帧:

id1  id2  A  B  C
0    1    1  5  3  0
1    1    1  7  5  4
2    1    2  3  4  3
3    1    2  4  5  4
4    2    1  2  4  3
5    2    1  4  5  4    

在此示例中:

  • 在第一组 (id1 == 1,id2 ==1) 中,在所有行中,A - B> 1, 所以条件-1
  • 在第二组(id1 ==1,id2 == 2)中,上述条件为满足,但在所有行中,A == C,因此条件 2True
  • 在最后一组(id1 ==2,id2 == 1)中,以上都不是 满足条件,因此条件 3True

因此,df.groupby(['id1','id2']).apply(udf_pd)的结果是:

id1  id2  A  B  C            D
0    1    1  5  3  0  Condition-1
1    1    1  7  5  4  Condition-1
2    1    2  3  4  3  Condition-2
3    1    2  4  5  4  Condition-2
4    2    1  2  4  3  Condition-3
5    2    1  4  5  4  Condition-3

我以前遇到过这个错误,我的理解是熊猫不确定它应该对哪个值运行条件。您可能希望使用.any().all()。考虑这些示例

>>> a = pd.Series([0,0,3])
>>> b = pd.Series([1,1,1])
>>> a - b
0   -1
1   -1
2    2
dtype: int64
>>> (a - b) >= 1
0    False
1    False
2     True
dtype: bool

你可以看到 (a-b)>= 1 的真实性有点模棱两可,向量中的第一个元素是假的,而其他元素是真的。

使用.any().all()将评估整个系列。

>>> ((a - b) >= 1).any()
True
>>> ((a - b) >= 1).all()
False

.any()检查系列中的任何元素是否为 True。而.all()检查是否所有元素都为 True。在这个例子中,他们不是。

你也可以看看这篇文章了解更多信息: 熊猫布尔值 .any() .all()

最新更新