6 回答

TA贡献1911条经验 获得超7个赞
我会建立一个系列列表,然后应用一个矢量化:np.all
contains = [frame['a'].str.contains(i) for i in letters]
resul = frame[np.all(contains, axis=0)]
它按预期提供:
a
0 a,b,c
1 a,c,f
3 a,z,c

TA贡献1765条经验 获得超5个赞
一种方法是使用 str.split
将列值拆分为列表,并检查是否为所获取列表的子集
:set(letters)
letters_s = set(letters)
frame[frame.a.str.split(',').map(letters_s.issubset)]
a
0 a,b,c
1 a,c,f
3 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'
)

TA贡献1876条经验 获得超5个赞
这也解决了它:
frame[frame['a'].apply(lambda x: np.all([*map(lambda l: l in x, letters)]))]

TA贡献1862条经验 获得超6个赞
您可以使用 :np.intersect1d
import pandas as pd
import numpy as np
frame = 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])
a
0 a,b,c
1 a,c,f
3 a,z,c

TA贡献1856条经验 获得超5个赞
使用集:是次级集:
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:
a
0 a,b,c
1 a,c,f
3 a,z,c

TA贡献1831条经验 获得超10个赞
IIUC 和布尔滤波器explode
这个想法是创建一个单一的系列,然后我们可以分组索引,使用累积总和来计算列表的真实发生次数
s = frame['a'].str.split(',').explode().isin(letters).groupby(level=0).cumsum()
print(s)
0 1.0
0 1.0
0 2.0
1 1.0
1 2.0
1 2.0
2 0.0
2 0.0
2 0.0
3 1.0
3 1.0
3 2.0
frame.loc[s[s.ge(2)].index.unique()]
out:
a
0 a,b,c
1 a,c,f
3 a,z,c
添加回答
举报