在Pandas中,如何选择在一列中有重复但在另一列中有不同值的行?

xyhw6mcr  于 2023-05-15  发布在  其他
关注(0)|答案(2)|浏览(215)

我有一个这样的dataframe:

import pandas as pd
records = [{'Name':'John', 'Country':'Canada'}, {'Name':'John', 'Country':'Canada'}, 
       {'Name':'Mary', 'Country':'US'}, {'Name':'Mary', 'Country':'Canada'}, 
       {'Name':'Mary', 'Country':'US'}, {'Name':'Stan', 'Country':'UK'},
       {'Name':'Stan', 'Country':'UK'}]
df = pd.DataFrame(records)
df
Name        Country
0   John    Canada
1   John    Canada
2   Mary    US
3   Mary    Canada
4   Mary    US
5   Stan    UK
6   Stan    UK

我想测试具有不同国家/地区值的名称。在这种情况下,我只想看到玛丽,因为她在国家列中有美国和加拿大。我可以排除约翰和斯坦,因为他们的记录都是同一个国家的。
有什么办法可以做到这一点吗?

zbsbpyhn

zbsbpyhn1#

第一步是找到具有超过1个唯一Country的名称,然后您可以在dataframe上使用loc来过滤这些值。

方法一:groupby

# groupby name and return a boolean of whether each has more than 1 unique Country
multi_country = df.groupby(["Name"]).Country.nunique().gt(1)

# use loc to only see those values that have `True` in `multi_country`:
df.loc[df.Name.isin(multi_country[multi_country].index)]

   Name Country
2  Mary      US
3  Mary  Canada
4  Mary      US

方法二:drop_duplicatesvalue_counts

您可以遵循相同的逻辑,但使用drop_duplicatesvalue_counts而不是groupby:

multi_country = df.drop_duplicates().Name.value_counts().gt(1)

df.loc[df.Name.isin(multi_country[multi_country].index)]

   Name Country
2  Mary      US
3  Mary  Canada
4  Mary      US

方法三:drop_duplicatesduplicated
注意:这将给予略有不同的结果:你只会看到玛丽的独特价值观,这可能是也可能不是所希望的…

您可以删除原始帧中的重复项,并仅返回在已消除重复项的帧中具有多个条目的名称:

no_dups = df.drop_duplicates()

no_dups[no_dups.duplicated(keep = False, subset="Name")]

   Name Country
2  Mary      US
3  Mary  Canada
abithluo

abithluo2#

首先,你可以按Name列分组,然后将Country列组合成列表。然后检查此列表中的值是否都相同。
此外,您可以使用布尔索引来选择具有不同值的行。

s = df.groupby('Name')['Country'].agg(list).apply(lambda l: all(map(lambda x: x == l[0], l)))

df_ = df[df['Name'].isin(s[~s].index)].drop_duplicates()
print(df_)

   Name Country
2  Mary      US
3  Mary  Canada

相关问题