检查熊猫列是否包含列表中的所有元素

我有一个像这样的df:

frame = pd.DataFrame({'a' : ['a,b,c', 'a,c,f', 'b,d,f','a,z,c']})

以及项目列表:

letters = ['a','c']

我的目标是从中获取至少包含 2 个元素的所有行frameletters

我想出了这个解决方案:

for i in letters:
    subframe = frame[frame['a'].str.contains(i)]

这给了我想要的东西,但就可伸缩性而言,它可能不是最好的解决方案。是否有任何“矢量化”解决方案?谢谢


喵喵时光机
浏览 81回答 6
6回答

Smart猫小萌

我会建立一个系列列表,然后应用一个矢量化:np.allcontains = [frame['a'].str.contains(i) for i in letters]resul = frame[np.all(contains, axis=0)]它按预期提供:       a0  a,b,c1  a,c,f3  a,z,c

POPMUISE

一种方法是使用 str.split 将列值拆分为列表,并检查是否为所获取列表的子集:set(letters)letters_s = set(letters)frame[frame.a.str.split(',').map(letters_s.issubset)]     a0  a,b,c1  a,c,f3  a,z,c基准:def serge(frame):    contains = [frame['a'].str.contains(i) for i in letters]    return frame[np.all(contains, axis=0)]def yatu(frame):    letters_s = set(letters)    return frame[frame.a.str.split(',').map(letters_s.issubset)]def austin(frame):    mask =  frame.a.apply(lambda x: np.intersect1d(x.split(','), letters).size > 0)    return frame[mask]def datanovice(frame):    s = frame['a'].str.split(',').explode().isin(letters).groupby(level=0).cumsum()    return frame.loc[s[s.ge(2)].index.unique()]perfplot.show(    setup=lambda n: pd.concat([frame]*n, axis=0).reset_index(drop=True),     kernels=[        lambda df: serge(df),        lambda df: yatu(df),        lambda df: df[df['a'].apply(lambda x: np.all([*map(lambda l: l in x, letters)]))],        lambda df: austin(df),        lambda df: datanovice(df),    ],    labels=['serge', 'yatu', 'bruno','austin', 'datanovice'],    n_range=[2**k for k in range(0, 18)],    equality_check=lambda x, y: x.equals(y),    xlabel='N')

慕运维8079593

这也解决了它:frame[frame['a'].apply(lambda x: np.all([*map(lambda l: l in x, letters)]))]

阿波罗的战车

您可以使用 :np.intersect1dimport pandas as pdimport numpy as npframe = pd.DataFrame({'a' : ['a,b,c', 'a,c,f', 'b,d,f','a,z,c']})letters = ['a','c']mask =  frame.a.apply(lambda x: np.intersect1d(x.split(','), letters).size > 0)print(frame[mask])    a0  a,b,c1  a,c,f3  a,z,c

RISEBY

使用集:是次级集:frame = pd.DataFrame({'a' : ['a,b,c', 'a,c,f', 'b,d,f','a,z,c','x,y']})letters = ['a','c']frame[frame['a'].apply(lambda x: set(letters).issubset(x))]Out:       a0  a,b,c1  a,c,f3  a,z,c

慕哥6287543

IIUC 和布尔滤波器explode这个想法是创建一个单一的系列,然后我们可以分组索引,使用累积总和来计算列表的真实发生次数s = frame['a'].str.split(',').explode().isin(letters).groupby(level=0).cumsum()print(s)0    1.00    1.00    2.01    1.01    2.01    2.02    0.02    0.02    0.03    1.03    1.03    2.0frame.loc[s[s.ge(2)].index.unique()]out:       a0  a,b,c1  a,c,f3  a,z,c
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python