2

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

# 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

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

提前致谢。

4

1 回答 1

5

isin我认为你可以在每一列上使用 Series 方法来实现你想要的:

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 中,您将能够使用新的 DataFrameisin方法(在当前 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

希望通过发布语法应该在发布时更好一些:

te[te.isin(tr).all(1)]
于 2013-08-07T20:37:17.537 回答