我有推荐人的用户/项目数据。我将它分成测试和训练数据,我需要确保在评估推荐者之前省略测试数据中的任何新用户或项目。 我的方法适用于小型数据集,但是当它变大时,它永远都需要。有更好的方法吗?
# 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
解决方案是正确的(任何新用户或项目都会导致整行被从测试中移除。但它的规模很慢。
提前致谢。
答案 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)]