我正在构建推荐系统,并在此处提供一些评级数据。 每行代表一个用户,每列代表一个产品,每个数据点代表用户对产品的评级。
in: np.array(df)
array([[ 0., 5., 5., 0., 0., 1.],
[ 5., 0., 4., 0., 1., 0.],
[ 4., 0., 5., 0., 0., 0.],
[ 5., 0., 5., 0., 0., 0.],
[ 4., 5., 0., 0., 0., 0.],
[ 0., 4., 0., 0., 0., 0.],
[ 0., 0., 0., 4., 4., 0.],
[ 0., 0., 0., 0., 5., 4.],
[ 0., 0., 0., 5., 0., 5.],
[ 0., 0., 0., 0., 5., 0.],
[ 0., 0., 0., 5., 0., 0.],
[ 5., 0., 0., 1., 0., 0.]])
我有一个看起来像上面的pandas数据框(我把它放到一个numpy数组中,以便在stackoverflow上更容易查看)。
对于每一行,我想选择10%的非零项,并将其设置为0.但是,我还想将每个修改过的单元格的行号和列号捕获到字典中。 (如果我将某个单元格设置为0,我想记录我已将哪个单元格更改为0)
我目前的解决方案是首先将所有零更改为NaN。然后,使用NaN的这个数据帧,当我将数据点设置为0时,我能够识别我修改了哪些单元格。
in: np.array(df[df.iloc[:] !=0])
out: array([[ nan, 5., 5., nan, nan, 1.],
[ 5., nan, 4., nan, 1., nan],
[ 4., nan, 5., nan, nan, nan],
[ 5., nan, 5., nan, nan, nan],
[ 4., 5., nan, nan, nan, nan],
[ nan, 4., nan, nan, nan, nan],
[ nan, nan, nan, 4., 4., nan],
[ nan, nan, nan, nan, 5., 4.],
[ nan, nan, nan, 5., nan, 5.],
[ nan, nan, nan, nan, 5., nan],
[ nan, nan, nan, 5., nan, nan],
[ 5., nan, nan, 1., nan, nan]])
但是,我不确定如何从每行中随机选择10%的非NaN数据,以及如何存储我已修改过的单元格的行索引和列名。 :
答案 0 :(得分:1)
我不知道矢量化方法是否可行(因为您从每一行中选择了可变数量的项目),但如果您愿意使用循环,那么它很简单Python(在Cython中它应该非常快):
import random
import math
from itertools import groupby
nonzero_indices = list(zip(*np.where(data != 0)))
indices_to_drop = []
for _, g in groupby(nonzero_indices, lambda x:x[0]):
li=list(g)
indices_to_drop += random.sample(li,math.ceil(len(li)/10))
# sample a tenth, rounded up, of each row's non-zero items
for idx in indices_to_drop:
data[idx] = 0
此外,如果您选择这样做,请在NumPy中执行此操作并稍后构建Pandas数据帧,因为通过pandas索引底层数组的速度非常慢。