从熊猫DF中随机选择非NaN数据(行和列必须是随机的)

时间:2017-10-13 02:28:44

标签: python pandas

我正在构建推荐系统,并在此处提供一些评级数据。 每行代表一个用户,每列代表一个产品,每个数据点代表用户对产品的评级。

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数据,以及如何存储我已修改过的单元格的行索引和列名。 :

1 个答案:

答案 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索引底层数组的速度非常慢。

相关问题