2017-10-13 59 views
0

我正在構建推薦系統,並在此處有一些評級數據。 每行代表一個用戶,每列代表一個產品,每個數據點代表用戶對產品的評分。從熊貓DF中隨機選擇非NaN數據(行和列必須是隨機的)

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.]]) 

我有一個數據幀熊貓看起來像上述(I把它放入一個numpy的陣列爲了容易觀看#1)。

對於每一行,我想選擇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%,以及如何存儲這些細胞的我已經修改了行索引和列名。 :

回答

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,後來建立了大熊貓據幀,因爲通過熊貓索引基礎數組是痛苦的緩慢。