2017-04-05 55 views
0

我想弄清楚,如何計算某些列中的唯一值取決於另一個值。我的數據框看起來是這樣的:熊貓計數值列表的唯一值

id_user id_track 
     1  1   
     1  2 
     1  4 
     3  1 
     3  1  
     3  4 
     1  1 
     2  5 

基本上我有一個表用戶和歌曲,他們聽取了ID的。我想爲每個用戶計數,他聽了多少獨特的歌曲並按此值排序。輸出應該是這樣的:

id_user uniqueTracks 
    1   3 
    3   2 
    2   1 

我試圖做到這一點以這種方式(聽證會是我的數據框):

uniqueTracks=[] #list of numbers of unique tracks 
for i in range(len(hearings['id_user'].unique())): 
    uniqueTracks.append(len(hearings[hearings['id_user']==i['titles'].unique()))   

,但它的工作原理非常緩慢的27萬行和70K獨特的表用戶。有沒有人有一個線索如何在熊貓做到這一點?預先感謝您:)

回答

1

這裏是一個NumPy方法的意思是性能 -

def nunique_groupby_col0_in_col1(a): 
    b = a[np.lexsort(a[:,::-1].T)] 

    m = np.r_[True, b[1:,1] != b[:-1,1]] 
    split_idx = np.r_[0, np.flatnonzero(b[1:,0] != b[:-1,0])+1] 
    m[split_idx] = 1 
    count = np.add.reduceat(m,split_idx) 
    userIDs = b[split_idx,0] 

    sidx = count.argsort()[::-1] 
    out_data = np.column_stack((userIDs, count))[sidx] 
    return out_data 

採樣運行 -

In [69]: df 
Out[69]: 
    id_user id_track 
0  1   1 
1  1   2 
2  1   4 
3  3   1 
4  3   1 
5  3   4 
6  1   1 
7  2   5 

In [70]: out_data = nunique_groupby_col0_in_col1(df.values) 
    ...: cnames = list(['id_user','uniqueTracks']) 
    ...: dfout = pd.DataFrame(out_data,columns=cnames) 
    ...: 

In [71]: dfout 
Out[71]: 
    id_user uniqueTracks 
0  1    3 
1  3    2 
2  2    1 
+0

哇!正是我想要的:)非常感謝你! 你能不能解釋一下,這裏發生了什麼?我知道你應用了一些lexsorting,但我不明白,你如何通過'a'和後面的代碼的排序值來訪問'a'?我的意思是 - 我瞭解功能,但不是它們的組合。 – tech2nick

2

使用groupby.nunique()計算每個用戶的獨特價值,並sort_values對結果進行排序:

df.groupby('id_user')['id_track'].nunique().sort_values(ascending=False) 

#id_user 
#1 3 
#3 2 
#2 1 
#Name: id_track, dtype: int64 

要返回的結果作爲一個數據幀,reset_index

df.groupby('id_user')['id_track'].nunique().reset_index().sort_values("id_track", ascending=False) 

enter image description here