我有两个数据框。数据框A具有由list
个ID值(命名项)组成的列。数据框B包含int
个ID值(名为ID)列。
数据框A:
date | items
2019-06-05 | [121, 123, 124]
2019-06-06 | [109, 125]
2019-06-07 | [108, 126]
数据框B:
name | id
item1 | 121
item2 | 122
item3 | 123
item4 | 124
item5 | 125
item6 | 126
我想过滤数据帧A,并仅将数据行B的items
列中所有id
的值都存在的行保留。
根据以上示例,结果应为:
数据框C:
date | items
2019-06-05 | [121, 123, 124]
(因为数据框B没有id == 108和id == 109的行)
如果items
是int
列,则可以使用:
dataframe_a[dataframe_a.items.isin(dataframe_b.id)]
如何在list
列中实现这一目标?
答案 0 :(得分:3)
您可以定义自定义函数,以搜索列表的所有元素是否在B数据框中,并将其与apply一起使用。
这里df1
是您的数据框架A,df2
是您的数据框架B:
sel = df1.apply(lambda x : all([i in df2['id'].unique() for i in x['items']]), axis=1)
finaldf = df1.loc[sel]
finaldf
是:
date items
0 2019-06-05 [121, 123, 124]
答案 1 :(得分:3)
我们可以使用issubset
l=[set(x).issubset(dfb.id.tolist())for x in df['items']]
Out[64]: [True, False, False]
然后
df=df[l]
答案 2 :(得分:2)
Valentino击败了我,所以想法是一样的
dataframe_a[dataframe_a['items'].apply(lambda lst: all(x in dataframe_b.id.values for x in lst))]
以下是您目前使用的方法的另外几句话:
pd.Series.isin
检查每个元素(在您的情况下为每个列表)是否以其他顺序整体存在。虽然您的列表是无序列表,但是对于一系列元组而言,顺序很重要,并且检查整体是否存在是正确/预期的行为。isin(dataframe_b.id)
,与调用isin(dataframe_b.id.index)
相同。 pd.Series就像字典,in
/ contains属性检查loc / index(或字典术语中的键),而不是值本身。如果您的位置/索引包含恰好与您的ID重叠的整数,则isin(dataframe_b.id)
可能会意外返回 true :In [17]: dataframe_b
Out[17]:
id
0 121
1 122
2 123
3 124
In [18]: 121 in dataframe_b.id
Out[18]: False
In [19]: 121 in dataframe_b.id.index
Out[19]: False
In [20]: 121 in dataframe_b.id.values
Out[20]: True
In [21]: 1 in dataframe_b.id
Out[21]: True