选择基于另一个布尔列的列中相等的行



我有以下数据帧:

dataset = {
'ID':[1,1,1,1,2,2,2,2],
'Animal': ["cat","bat","cat","bat","monkey","monkey","bird","bird"],
'Bool':[True,False,False,False,True,False,False,False],}
df = pd.DataFrame(dataset)
df.groupby(["ID"])

我想从df["Bool"]True的另一行中为每个按ID分组的子集选择列df["Animal"]等于df["Animal"]的行。结果将存储在df["IS_Same"]中,如预期输出所示。

预期输出:

ID  Animal   Bool  Is_Same
0   1     cat   True    False
1   1     bat  False    False
2   1     cat  False     True
3   1     bat  False    False
4   2  monkey   True    False
5   2  monkey  False     True
6   2    bird  False    False
7   2    bird  False    False

有没有一种方法可以在不使用循环的情况下轻松做到这一点?

让我们按照IDAnimal使用anytransformBool

df['Same'] = ~df['Bool'] & df.groupby(['ID', 'Animal'])['Bool'].transform('any')

ID  Animal   Bool   Same
0   1     cat   True  False
1   1     bat  False  False
2   1     cat  False   True
3   1     bat  False  False
4   2  monkey   True  False
5   2  monkey  False   True
6   2    bird  False  False
7   2    bird  False  False

这里有一个选项-在组内向前和向后看

import pandas as pd
dataset = {
'ID':[1,1,1,1,2,2,2,2],
'Animal': ["cat","bat","cat","bat","monkey","monkey","bird","bird"],
'Bool':[True,False,False,False,True,False,False,False],}
df = pd.DataFrame(dataset)
df['Is_Same'] = df.groupby(['ID','Animal'])['Bool'].shift() | df.groupby(['ID','Animal'])['Bool'].shift(-1)

您可以尝试groupby并将Animal列与对应的第一个TrueAnimal进行比较

out = (df.groupby(["ID"])
.apply(lambda g: g.assign(Is_Same=g['Animal'].eq(g.loc[g['Bool'], 'Animal'].item())))
.pipe(lambda df: df.assign(Is_Same=df['Is_Same'].mask(df['Bool'], False))))
print(out)
ID  Animal   Bool  Is_Same
0   1     cat   True    False
1   1     bat  False    False
2   1     cat  False     True
3   1     bat  False    False
4   2  monkey   True    False
5   2  monkey  False     True
6   2    bird  False    False
7   2    bird  False    False

这里有一个使用group_by的简单而全面的解决方案,它可以推广到组中的任何数量的数据。

df = pd.DataFrame(dataset)
df['Is_same'] = False
df_grouped =  = df.groupby(['ID', 'Animal'])
for group_name, df_group in df_grouped:
for row_index, row in df_group.iterrows():
if(any(df_group[~df_group.index.isin([row_index])].Bool)):
df.loc[row_index, 'Is_same'] = True

这为我们提供了预期的输出

ID  Animal   Bool  Is_same
0   1     cat   True    False
1   1     bat  False    False
2   1     cat  False     True
3   1     bat  False    False
4   2  monkey   True    False
5   2  monkey  False     True
6   2    bird  False    False
7   2    bird  False    False

相关内容

最新更新