3 votes

Pandas crosstab sur une très grande matrice ?

J'ai un cadre de données de dimensions (42 millions de lignes, 6 colonnes) sur lequel je dois effectuer un tableau croisé pour obtenir le nombre d'événements spécifiques pour chaque personne de l'ensemble de données, ce qui donnera une très grande matrice éparse de taille ~1,5 million de lignes par 36 000 colonnes. Lorsque j'essaie de le faire avec la fonction pandas crosstab (pd.crosstab), la mémoire de mon système est saturée. Existe-t-il un moyen d'effectuer ce tableau croisé par morceaux et de joindre les cadres de données résultants ? Pour être clair, chaque ligne du tableau croisé comptera le nombre de fois qu'un événement s'est produit pour chaque personne dans l'ensemble de données (c'est-à-dire que chaque ligne est une personne, chaque entrée de colonne est le nombre de fois que cette personne a participé à un événement spécifique). L'objectif final est de factoriser la matrice personne-événement résultante en utilisant PCA/SVD.

4voto

piRSquared Points 159

Configuration

source_0 = [*'ABCDEFGHIJ']
source_1 = [*'abcdefghij']

np.random.seed([3, 1415])

df = pd.DataFrame({
    'source_0': np.random.choice(source_0, 100),
    'source_1': np.random.choice(source_1, 100),
})

df

   source_0 source_1
0         A        b
1         C        b
2         H        f
3         D        a
4         I        h
..      ...      ...
95        C        f
96        F        a
97        I        j
98        I        d
99        J        b

Utilisez pd.factorize pour obtenir une factorisation entière... et des valeurs uniques

ij, tups = pd.factorize(list(zip(*map(df.get, df))))
result = dict(zip(tups, np.bincount(ij)))

Il s'agit déjà d'une forme compacte. Mais vous pouvez la convertir en un pandas.Series y unstack pour vérifier que c'est bien ce que nous voulons.

pd.Series(result).unstack(fill_value=0)

   a  b  c  d  e  f  g  h  i  j
A  2  1  0  0  0  1  0  2  1  1
B  0  1  0  0  0  1  0  1  0  1
C  0  3  1  3  0  2  0  0  0  0
D  3  0  0  2  0  0  1  3  0  2
E  3  0  0  1  0  1  2  5  0  0
F  4  0  2  1  1  1  1  1  1  0
G  0  2  1  0  0  2  3  0  3  1
H  1  3  2  0  2  1  1  1  0  2
I  2  2  1  1  2  0  1  2  0  2
J  0  1  1  0  1  1  0  1  0  1

Utilisation de sparse

from scipy.sparse import csr_matrix

i, r = pd.factorize(df['source_0'])
j, c = pd.factorize(df['source_1'])
ij, tups = pd.factorize(list(zip(i, j)))

a = csr_matrix((np.bincount(ij), tuple(zip(*tups))))

b = pd.DataFrame.sparse.from_spmatrix(a, r, c).sort_index().sort_index(axis=1)

b

   a  b  c  d  e  f  g  h  i  j
A  2  1  0  0  0  1  0  2  1  1
B  0  1  0  0  0  1  0  1  0  1
C  0  3  1  3  0  2  0  0  0  0
D  3  0  0  2  0  0  1  3  0  2
E  3  0  0  1  0  1  2  5  0  0
F  4  0  2  1  1  1  1  1  1  0
G  0  2  1  0  0  2  3  0  3  1
H  1  3  2  0  2  1  1  1  0  2
I  2  2  1  1  2  0  1  2  0  2
J  0  1  1  0  1  1  0  1  0  1

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X