Pandas数据框按列中包含列表的字符串对子集进行筛选

3

我有一个复杂的、大型的pandas数据框,其中一列X可能包含一个列表或一个列表的列表。但我想知道这个解决方案是否适用于任何内容,因此我给出了一个模拟示例,其中X的一个元素也是一个字符串:

df1 = pd.DataFrame({
    'A': [1, 1, 3], 
    'B': ['a', 'e', 'f'], 
    'X': ['something', ['hello'], [['something'],['hello']]]}
)

我想获取数据框df2的子集,其中列X包含子字符串“hello”,当其中的任何内容被读为字符串时。
>>> df2
   A  B                       X
0  1  e                 [hello]
1  3  f  [[something], [hello]]

我已经尝试了大量的str()和.str.contains、apply、map、.find()、列表推导等组合,但似乎没有什么方法能够在不进入循环的情况下完成任务(相关问题请查看这里这里)。我错过了什么吗?

3个回答

6

str.contains 前添加 astype

df1[df1.X.astype(str).str.contains('hello')]
Out[538]: 
   A  B                       X
1  1  e                 [hello]
2  3  f  [[something], [hello]]

@JRCX yw~ :-) 祝你编程愉快。 - BENY

5
你可以使用np.ravel()将嵌套列表扁平化,并使用in运算符。
df1[df1['X'].apply(lambda x: 'hello' in np.ravel(x))]

    A   B   X
1   1   e   [hello]
2   3   f   [[something], [hello]]

2

借鉴@wim的想法https://stackoverflow.com/a/49247980/2336654

最常见的解决方案是允许任意嵌套列表。此外,我们可以将重点放在字符串元素相等而不是包含上。

# This import is for Python 3
# for Python 2 use `from collections import Iterable`
from collections.abc import Iterable

def flatten(collection):
    for x in collection:
        if isinstance(x, Iterable) and not isinstance(x, str):
            yield from flatten(x)
        else:
            yield x

df1[df1.X.map(lambda x: any('hello' == s for s in flatten(x)))]

   A  B                       X
1  1  e                 [hello]
2  3  f  [[something], [hello]]

所以现在如果我们把它复杂化
df1 = pd.DataFrame({
    'A': [1, 1, 3, 7, 7], 
    'B': ['a', 'e', 'f', 's', 's'], 
    'X': [
        'something',
        ['hello'],
        [['something'],['hello']],
        ['hello world'],
        [[[[[['hello']]]]]]
    ]}
)

df1

   A  B                       X
0  1  a               something
1  1  e                 [hello]
2  3  f  [[something], [hello]]
3  7  s           [hello world]
4  7  s     [[[[[['hello']]]]]]

我们的过滤器不捕获hello world,但会捕获非常嵌套的hello

df1[df1.X.map(lambda x: any('hello' == s for s in flatten(x)))]

   A  B                       X
1  1  e                 [hello]
2  3  f  [[something], [hello]]
4  7  s     [[[[[['hello']]]]]]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接