Ich habe Daten, die ungefähr so aussehen:

Numpy array:

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

Es ist wie eine User-Item-Matrix. Ich möchte eine spärliche Matrix mit der Form konstruieren: Anzahl_der_Elemente, Anzahl_der_Benutzer, die 1 ergibt, wenn der Benutzer einen Artikel bewertet / gekauft hat, oder 0, wenn er dies nicht getan hat. Für das obige Beispiel sollte die Form also (5,6) sein. Dies ist nur ein Beispiel, es gibt Tausende von Benutzern und Tausende von Elementen.

Derzeit mache ich dies mit zwei for-Schleifen. Gibt es eine schnellere / pythonische Möglichkeit, dasselbe zu erreichen?

Gewünschte Leistung:

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

Wo Zeilen: abc,def,ghi,fg,f76 und Spalten: a,b,c,d,e,f

6
Abhishek Thakur 14 Aug. 2015 im 13:39

4 Antworten

Beste Antwort

Am einfachsten ist es, den Benutzern und Elementen ganzzahlige Beschriftungen zuzuweisen und diese als Koordinaten in der Sparse-Matrix zu verwenden, zum Beispiel:

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))
2
15 Aug. 2015 im 12:42

Hier ist mein Ansatz mit Pandas. Lassen Sie mich wissen, ob es besser funktioniert:

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

Hier sind die Beispieldatenrahmen für den obigen Code:

    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

Auch für den Fall, dass Sie groupby dazu bringen möchten, die Funktionsausführung anzuwenden Parallel dazu könnte diese Frage hilfreich sein: Parallelisierung nach Pandas Groupby anwenden

0
Community 23 Mai 2017 im 10:28

pandas.get_dummies bietet die einfachere Möglichkeit, Kategorien zu konvertieren Spalten zu spärlicher Matrix

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
1
Yung 17 Apr. 2018 im 03:46

Folgendes könnte ich mir einfallen lassen:

Sie müssen vorsichtig sein, da np.unique die Elemente sortiert, bevor sie zurückgegeben werden. Daher unterscheidet sich das Ausgabeformat geringfügig von dem in der Frage angegebenen.

Darüber hinaus müssen Sie das Array in eine Liste von Tupeln konvertieren, da ('a', 'abc') in [('a', 'abc'), ('b', 'def')] True zurückgibt, ['a', 'abc'] in [['a', 'abc'], ['b', 'def']] jedoch nicht.

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]])
0
Daniel Lenz 14 Aug. 2015 im 13:42