Идентификатор группы и unstack (или сумма) на большой матрице (3x3 млн.) - PullRequest
0 голосов
/ 24 августа 2018

У меня есть некоторые данные в файле .csv, которые описывают соединения в сети.

        index  c     id_1   id_2
0           0  1        8     10
1           1  1        7     10
2           2  1        7     10
3           3  1  2189149     29
4           4  1       27     29

, где c обозначает соединение.Эти данные имеют форму (3114045, 4) и занимают ~ 100 мб.

Я бы хотел посчитать, сколько раз id_1 связан с id_2.Я могу сделать это либо с помощью

adj_pivot = pd.pivot_table(data=df, 
                     index="id_1", 
                     columns="id_2", 
                     values="c", 
                     aggfunc=np.sum)

, либо в качестве альтернативы - и намного быстрее - я могу сделать

adj_group = df.groupby(["id_1", "id_2"]).size().unstack(fill_value=0)

в любом случае, это дает мне желаемый результат:

id_2     10   29
id_1            
7        2.0  0
8        1.0  0
27       0    1.0
2189149  0    1.0

Моя проблема заключается в том, что если я сделаю описанный выше pivot / groupby с пандами, мне потребуется ~ 5300 ГБ оперативной памяти.

Разреженная версия полной (3114045, 4) структура занимает 56 байтов согласно sys.getsizeof(scipy.sparse.csr_matrix(df)).Попытка описанного выше метода с 100 000 строками и затем его редкость, похоже, я могу сжать размер матрицы с коэффициентом 10^-8.


Итак, мой вопрос: как бы я повторил описанную выше опорную точку + sum / groupby + на разреженную структуру?Если это невозможно, есть ли хорошая тактика для этого в партиях?

Я посмотрел на ответ здесь , но он все еще кажется мне несколько загадочным.

1 Ответ

0 голосов
/ 24 августа 2018

Это должно работать:

grouped = df.groupby(["id_1", "id_2"]).size().reset_index()
values = grouped.values.T
scipy.sparse.csr_matrix((values[2], (values[0], values[1])))

<2189150x30 sparse matrix of type '<class 'numpy.int64'>'
    with 4 stored elements in Compressed Sparse Row format>
...