我们在一列中包含带有列表的数据框。无法找到简单的方法来过滤包含列表中包含值的行的数据帧。
df = pd.DataFrame({'lists':[['a', 'c'], ['a', 'b', 'd'], ['c', 'd']]})
例如,我只需要在列表中包含'a'的行。 我设法通过“申请”获得了它。
df[df.lists.apply(lambda x: True if 'a' in x else False)]
>>> lists
>>>0 [a, c]
>>>1 [a, b, d]
是否有类似.isin()的内容,反之亦然? 获得所需行的最佳方法是什么? 感谢。
答案 0 :(得分:1)
最简单的是apply
使用in
:
df1 = df[df.lists.apply(lambda x: 'a' in x)]
但是如果要检查a
创建DataFrame
,但它有点复杂:
df1 = df[pd.DataFrame(df.lists.values.tolist()).eq('a').any(axis=1)]
另一种解决方案是str.join
使用str.contains
:
df1 = df[df.lists.str.join(',').str.contains('a')]
print (df1)
lists
0 [a, c]
1 [a, b, d]
答案 1 :(得分:0)
通过列表推导进行布尔索引是一种方式:
df = pd.DataFrame({'lists':[['a', 'c'], ['a', 'b', 'd'], ['c', 'd']]})
df[['a' in x for x in df['lists'].values]]
# lists
# 0 [a, c]
# 1 [a, b, d]
一些绩效基准测试:
df = pd.DataFrame({'lists':[['a', 'c'], ['a', 'b', 'd'], ['c', 'd']]})
df = pd.concat([df]*100000)
def jez1(df):
return df[df.lists.apply(lambda x: 'a' in x)]
def jez2(df):
return df[pd.DataFrame(df.lists.values.tolist()).eq('a').any(axis=1)]
def jez3(df):
return df[df.lists.str.join(',').str.contains('a')]
def jp(df):
return df[['a' in x for x in df['lists'].values]]
%timeit jez1(df) # 87ms
%timeit jez2(df) # 122ms
%timeit jez3(df) # 416ms
%timeit jp(df) # 53ms