【问题标题】:Pandas count unique values for list of values熊猫计算值列表的唯一值
【发布时间】:2017-04-06 03:40:51
【问题描述】:

我想弄清楚,如何根据另一个值计算某个列中的唯一值。我的 DataFrame 如下所示:

   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

我尝试以这种方式进行(听证会是我的 DataFrame):

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()))           

但对于 2700 万行和 70k 唯一用户的表,它的运行速度非常慢。有谁知道如何在熊猫中做到这一点?提前谢谢你:)

【问题讨论】:

    标签: pandas dataframe unique-values


    【解决方案1】:

    使用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)
    

    【讨论】:

      【解决方案2】:

      这是一种旨在提高性能的 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
      

      【讨论】:

      • 哇!正是我想要的:)非常感谢!您能否解释一下,这里发生了什么?我知道您应用了一些 lexsorting,但我不明白,您如何通过“a”的排序值和以后的代码访问“a”?我的意思是 - 我了解这些功能,但不了解它们的组合。
      猜你喜欢
      • 2021-03-17
      • 2019-02-12
      • 1970-01-01
      • 1970-01-01
      • 2015-01-14
      • 1970-01-01
      • 1970-01-01
      • 2017-05-30
      • 1970-01-01
      相关资源
      最近更新 更多