Python Pandas - 如果不在第二个数据帧中,则从第一个数据帧中删除值

时间:2013-08-07 19:42:13

标签: python pandas

我有推荐人的用户/项目数据。我将它分成测试和训练数据,我需要确保在评估推荐者之前省略测试数据中的任何新用户或项目。 我的方法适用于小型数据集,但是当它变大时,它永远都需要。有更好的方法吗?

# Test set for removing users or items not in train
te = pd.DataFrame({'user': [1,2,3,1,6,1], 'item':[16,12,19,15,13,12]})
tr = pd.DataFrame({'user': [1,2,3,4,5], 'item':[11,12,13,14,15]})
print "Training_______"
print tr
print "\nTesting_______"
print te

# By using two joins and selecting the proper indices, all 'new' members of test set are removed
b = pd.merge( pd.merge(te,tr, on='user', suffixes=['', '_d']) , tr, on='item', suffixes=['', '_d'])[['user', 'item']]
print "\nSolution_______"
print b

给出:

Training_______
   item  user
0    11     1
1    12     2
2    13     3
3    14     4
4    15     5

Testing_______
   item  user
0    16     1
1    12     2
2    19     3
3    15     1
4    13     6
5    12     1

Solution_______
   user  item
0     1    15
1     1    12
2     2    12

解决方案是正确的(任何新用户或项目都会导致整行被从测试中移除。但它的规模很慢。

提前致谢。

1 个答案:

答案 0 :(得分:5)

我认为您可以使用每个列上的isin系列方法实现您想要的效果:

In [11]: te['item'].isin(tr['item']) & te['user'].isin(tr['user'])
Out[11]:
0    False
1     True
2    False
3     True
4    False
5     True
dtype: bool

In [12]: te[te['item'].isin(tr['item']) & te['user'].isin(tr['user'])]
Out[12]:
   item  user
1    12     2
3    15     1
5    12     1

在0.13中,您将能够使用新的DataFrame isin方法(on current master):

In [21]: te[te.isin(tr.to_dict(outtype='list')).all(1)]
Out[21]:
   item  user
1    12     2
3    15     1
5    12     1

希望在发布时发布syntax should be a bit better

te[te.isin(tr).all(1)]