简化 Pandas 中的布尔索引条件

Simplify Boolean Indexing Conditions in Pandas

提问人:anon124083 提问时间:6/20/2023 最后编辑:Goku - stands with Palestineanon124083 更新时间:6/20/2023 访问量:46

问:

我有两列,它们包含“是”或“否”值:

  • 伙伴
  • 家属

我最初编写此代码是为了根据这两列中的值生成另一列(见下文):

conditions = [
    # either dependents, partner, or both 
    ((cleaned_df["Partner"] == "Yes") & (cleaned_df["Dependents"] == "Yes")) | ((cleaned_df["Partner"] == "No") & (cleaned_df["Dependents"] == "Yes")) | ((cleaned_df["Partner"] == "Yes") & (cleaned_df["Dependents"] == "No")),
    # neither partner nor dependents
    (cleaned_df["Partner"] == "No") & (cleaned_df["Dependents"] == "No")
]

但是,第一个条件有点罗嗦,我想知道是否有更雄辩的方法来重写此代码。提前致谢!

python-3.x pandas 帧数据 操作

评论


答:

2赞 Goku - stands with Palestine 6/20/2023 #1

我举一个最小的例子:

import pandas as pd
data = {'Partner' : ['Yes','No','Yes','No'] , 'Dependents': ['No','No','Yes','Yes']}
df = pd.DataFrame(data)

print(df)
Partner Dependents
0   Yes No
1   No  No
2   Yes Yes
3   No  Yes

您可以简单地执行以下操作:

(df["Partner"] == "Yes") | (df["Dependents"] == "Yes")

0     True
1    False
2     True
3     True
dtype: bool

解释:如果任何一个是真的,那么它将是,如果它们都是,那么它将是TrueFalseFalse.

1赞 Panda Kim 6/20/2023 #2

dict1 = {'colA': {0: 'a0', 1: 'a1', 2: 'a2', 3: 'a3', 4: 'a4'}, 
         'Partner': {0: 'Yes', 1: 'Yes', 2: 'No', 3: 'No', 4: 'Yes'}, 
         'Dependents': {0: 'Yes', 1: 'No', 2: 'Yes', 3: 'No', 4: 'No'}}
df = pd.DataFrame(dict1)

df

    colA    Partner Dependents
0   a0      Yes     Yes
1   a1      Yes     No
2   a2      No      Yes
3   a3      No      No
4   a4      Yes     No

法典

索引两列并制作为布尔值并使用 funcany

df[['Partner', 'Dependents']].eq('Yes').any(axis=1)

结果:

0     True
1     True
2     True
3    False
4     True
dtype: bool

将结果转换为条件列

df.assign(conditions=df[['Partner', 'Dependents']].eq('Yes').any(axis=1))

df

    colA    Partner Dependents  conditions
0   a0      Yes     Yes         True
1   a1      Yes     No          True
2   a2      No      Yes         True
3   a3      No      No          False
4   a4      Yes     No          True
0赞 Corralien 6/20/2023 #3

与其他答案一样,您正在寻找 OR 表 ():|

>>> df_or
  Partner Dependents  Expected
0      No         No     False
1      No        Yes      True
2     Yes         No      True
3     Yes        Yes      True

然而,@Phoenix建议的一个有趣的表是 NOR 表 ():^

>>> df_nor
  Partner Dependents  Expected
0      No         No      True
1      No        Yes     False
2     Yes         No     False
3     Yes        Yes     False

因此,只需检查“伴侣和家属”是否为“否”并反转掩码:

>>> ~(df['Partner'].eq('No') & df['Dependents'].eq('No'))
0    False
1     True
2     True
3     True
dtype: bool

更简洁的方式:

>>> ~df[['Partner', 'Dependents']].eq('No').all(axis=1)
0    False
1     True
2     True
3     True
dtype: bool

所以你的决赛应该是这样的:

m = df[['Partner', 'Dependents']].eq('Yes').any(axis=1)
conditions = [m, ~m]

使用 numpy,您可以使用:

# val1 for "either dependents, partner, or both" condition
# val2 for "neither partner nor dependents"
df['Target'] = np.where(m, "val1", "val2")