我有一个包含4列的Pandas数据框 - 如下所示:
A B C D
2 c {4889, 9978, 1230, 4921} {30} 4
4 m {4889, 9978, 1230, 4921} {30} 4
0 a {4889, 1230, 4921} {30} 3
7 q {1240, 4921} {30} 2
9 x {9978, 1230} {30} 2
另外,我有一个这样的列表:
[[1230,4889],[1240, 4921]]
我想从数据框中选择那些列B值是任何列表项的超集的行。对于给定的示例,输出将是:
A B C D
2 c {4889, 9978, 1230, 4921} {30} 4
4 m {4889, 9978, 1230, 4921} {30} 4
0 a {4889, 1230, 4921} {30} 3
7 q {1240, 4921} {30} 2
任何好方法吗?它并不像做以下事情一样直接:
df.loc[df['B'] == 'xyz']
答案 0 :(得分:2)
通过设置操作使用numpy
广播。
注意:>=
for sets返回正确值,右侧是左侧的子集。相等部分允许相等的集合。
s = np.array([set(l) for l in [[1230, 4889], [1240, 4921]]])
m = (df['B'].values >= s[:, None]).any(0)
df[m]
A B C D
2 c {4889, 9978, 1230, 4921} {30} 4
4 m {4889, 9978, 1230, 4921} {30} 4
0 a {4889, 1230, 4921} {30} 3
7 q {1240, 4921} {30} 2
答案 1 :(得分:0)
一种天真的方法,只需检查列表中每个元素的包含。
import pandas as pd
from io import StringIO
df = pd.read_csv(StringIO(""" A B C D
2 c {4889, 9978, 1230, 4921} {30} 4
4 m {4889, 9978, 1230, 4921} {30} 4
0 a {4889, 1230, 4921} {30} 3
7 q {1240, 4921} {30} 2
9 x {9978, 1230} {30} 2""",
), sep=r' +')
df['B'] = df.B.apply(eval)
lst = [[1230,4889],[1240, 4921]]
lst_sets = [set(l) for l in lst]
df_res = df[df.B.apply(lambda s: any(not(s2 - s) for s2 in lst_sets))]