【问题标题】:construct sparse matrix using categorical data使用分类数据构造稀疏矩阵
【发布时间】:2015-11-07 14:16:19
【问题描述】:

我有一个看起来像这样的数据:

numpy 数组:

[[a, abc],
[b, def],
[c, ghi],
[d, abc],
[a, ghi],
[e, fg],
[f, f76],
[b, f76]]

它就像一个用户项目矩阵。 我想构造一个形状为 number_of_items, num_of_users 的稀疏矩阵,如果用户评价/购买了一个项目,则为 1,如果没有,则为 0。因此,对于上面的示例,形状应该是 (5,6)。这只是一个示例,有数千个用户和数千个项目。

目前我正在使用两个 for 循环来执行此操作。有没有更快/pythonic 的方法来实现同样的目标?

想要的输出:

1,0,0,1,0,0
0,1,0,0,0,0
1,0,1,0,0,0
0,0,0,0,1,0
0,1,0,0,0,1

其中行:abc,def,ghi,fg,f76 和列:a,b,c,d,e,f

【问题讨论】:

  • 你能明确给出你想要的输出吗?
  • 添加到问题中

标签: python numpy scipy sparse-matrix


【解决方案1】:

pandas.get_dummies 提供了将分类列转换为稀疏矩阵的更简单方法

import pandas as pd
#construct the data
x = pd.DataFrame([['a', 'abc'],['b', 'def'],['c' 'ghi'],
                 ['d', 'abc'],['a', 'ghi'],['e', 'fg'],
                 ['f', 'f76'],['b', 'f76']], 
                 columns = ['user','item'])
print(x)
#    user  item
# 0     a   abc
# 1     b   def
# 2     c   ghi
# 3     d   abc
# 4     a   ghi
# 5     e    fg
# 6     f   f76
# 7     b   f76
for col, col_data in x.iteritems():
    if str(col)=='item':
        col_data = pd.get_dummies(col_data, prefix = col)
        x = x.join(col_data)
print(x)
#    user  item  item_abc  item_def  item_f76  item_fg  item_ghi
# 0     a   abc         1         0         0        0         0
# 1     b   def         0         1         0        0         0
# 2     c   ghi         0         0         0        0         0
# 3     d   abc         1         0         0        0         0
# 4     a   ghi         0         0         0        0         1
# 5     e    fg         0         0         0        1         0
# 6     f   f76         0         0         1        0         0
# 7     b   f76         0         0         1        0         0

【讨论】:

    【解决方案2】:

    最简单的方法是将整数标签分配给用户和项目,并将它们用作稀疏矩阵中的坐标,例如:

    import numpy as np
    from scipy import sparse
    
    users, I = np.unique(user_item[:,0], return_inverse=True)
    items, J = np.unique(user_item[:,1], return_inverse=True)
    
    points = np.ones(len(user_item), int)
    mat = sparse.coo_matrix(points, (I, J))
    

    【讨论】:

      【解决方案3】:

      这是我使用 pandas 的方法,如果效果更好,请告诉我:

      #create dataframe from your numpy array
      x = pd.DataFrame(x, columns=['User', 'Item'])
      
      #get rows and cols for your sparse dataframe    
      cols = pd.unique(x['User']); ncols = cols.shape[0]
      rows = pd.unique(x['Item']); nrows = rows.shape[0]
      
      #initialize your sparse dataframe, 
      #(this is not sparse, but you can check pandas support for sparse datatypes    
      spdf = pd.DataFrame(np.zeros((nrow, ncol)), columns=cols, index=rows)    
      
      #define apply function    
      def hasUser(xx):
          spdf.ix[xx.name,  xx] = 1
      
      #groupby and apply to create desired output dataframe    
      g = x.groupby(by='Item', sort=False)
      g['User'].apply(lambda xx: hasUser(xx))
      

      这是上述代码的示例数据框:

          spdf
          Out[71]: 
               a  b  c  d  e  f
          abc  1  0  0  1  0  0
          def  0  1  0  0  0  0
          ghi  1  0  1  0  0  0
          fg   0  0  0  0  1  0
          f76  0  1  0  0  0  1
      
          x
          Out[72]: 
            User Item
          0    a  abc
          1    b  def
          2    c  ghi
          3    d  abc
          4    a  ghi
          5    e   fg
          6    f  f76
          7    b  f76
      

      另外,如果你想让 groupby 应用函数执行 parallel ,这个问题可能会有所帮助: Parallelize apply after pandas groupby

      【讨论】:

        【解决方案4】:

        这是我能想到的:

        您需要小心,因为np.unique 会在返回项目之前对其进行排序,因此输出格式与您在问题中给出的格式略有不同。

        此外,您需要将数组转换为元组列表,因为('a', 'abc') in [('a', 'abc'), ('b', 'def')] 将返回True,但['a', 'abc'] in [['a', 'abc'], ['b', 'def']] 不会。

        A = np.array([
        ['a', 'abc'],
        ['b', 'def'],
        ['c', 'ghi'],
        ['d', 'abc'],
        ['a', 'ghi'],
        ['e', 'fg'],
        ['f', 'f76'],
        ['b', 'f76']])
        
        customers = np.unique(A[:,0])
        items = np.unique(A[:,1])
        A = [tuple(a) for a in A]
        combinations = it.product(customers, items)
        C = np.array([b in A for b in combinations], dtype=int)
        C.reshape((values.size, customers.size))
        >> array(
          [[1, 0, 0, 0, 1, 0],
           [1, 1, 0, 0, 0, 0],
           [0, 0, 1, 1, 0, 0],
           [0, 0, 0, 0, 0, 1],
           [0, 0, 0, 1, 0, 0]])
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-11-29
          • 2020-12-01
          • 1970-01-01
          • 2010-11-02
          • 2018-01-19
          • 2016-10-04
          • 2017-09-22
          • 1970-01-01
          相关资源
          最近更新 更多