Pandas .isin()用于列的每一行中的值列表

时间:2017-05-23 04:57:10

标签: python pandas

我遇到一个小问题:我的DataFrame中有一个列,它有多行,每行都有一个或多个值,以“M”字母开头,后跟3位数字。如果值超过1,则用逗号分隔。 我想打印出一个DataFrame视图,只显示1列保存我指定值的行(例如,我希望它们保存列表中的任何项目['M111','M222']。 我已经开始以下列方式构建我的布尔掩码:

df[df['Column'].apply(lambda x: x.split(', ').isin(['M111', 'M222']))]

在我看来,.apply()和.split()方法首先将'Column'值转换为每行中包含1个或多个值的列表,然后.isin()方法确认是否有每行中项目列表中的项目都在指定值列表中['M111','M222']。 但实际上,我得到错误

,而不是获得所需的DataFrame视图
'TypeError: unhashable type: 'list'

我做错了什么?

亲切的问候, Greem

2 个答案:

答案 0 :(得分:4)

我认为你需要:

df2 = df[df['Column'].str.contains('|'.join(['M111', 'M222']))]

答案 1 :(得分:4)

您只能使用Pandas对象访问isin()方法。但是split()会返回一个列表。将split()中的Series包裹起来将起作用:

# sample data
data = {'Column':['M111, M000','M333, M444']}
df = pd.DataFrame(data)

print(df)
       Column
0  M111, M000
1  M333, M444

现在将split()包裹在Series中 请注意,isin()将返回一个布尔值列表,每个元素对应一个来自split()的元素。您想知道“列表中的任何项目是否在指定值列表中”,请将any()添加到您的apply函数中。

df[df['Column'].apply(lambda x: pd.Series(x.split(', ')).isin(['M111', 'M222']).any())]

输出:

       Column
0  M111, M000

正如其他人所指出的那样,有更简单的方法可以实现最终目标。但这是解决您遇到isin()时遇到的具体问题的方法。