Как эффективно преобразовать субдиректорию в матрицу в Python - PullRequest
0 голосов
/ 25 ноября 2018

У меня есть словарь, подобный этому:

{'test2':{'hi':4,'bye':3}, 'religion.christian_20674': {'path': 1, 'religious': 1, 'hi':1}}

значение этого словаря само по себе является словарём.

как должен выглядеть мой вывод:

enter image description here

как я могу сделать это эффективно?

Я прочитал этот пост, форма матрицы которого отличается от моей.

этот один был ближе всего к моему случаю, но у него был набор внутри словаря, а не другой словарь.

В моем вопросе отличается то, что я хочу также преобразоватьзначение внутреннего словаря как значения матрицы.

Я думал что-то вроде этого:

doc_final =[[]]
for item in dic1:
    for item2, value in dic1[item]:
        doc_final[item][item2] = value

, но это было не так.

Спасибо заВаша помощь:)

Ответы [ 2 ]

0 голосов
/ 25 ноября 2018

Кажется, что в Pandas или Numpy нет встроенных способов разделить ваши ряды так, как вы хотите.К счастью, вы можете сделать это с помощью одного словаря.Функция splitsubdicts, показанная ниже, обеспечивает такое понимание, а функция todf завершает весь процесс преобразования:

def splitsubdicts(d):
    return {('%s_%d' % (k0, i + 1)):{k1:v1} for k0,v0 in d.items() for i,(k1,v1) in enumerate(v0.items())}

def todf(d):
    # .fillna(0) replaces the missing data with 0 (by default NaN is assigned to missing data)
    return pd.DataFrame(splitsubdicts(splitsubdicts(d))).T.fillna(0)

Вы можете использовать todf, например:

d = {'Test2': {'hi':4, 'bye':3}, 'religion.christian_20674': {'path': 1, 'religious': 1, 'hi':1}}
df = todf(d)
print(df)

Вывод:

                              bye   hi  path  religious
Test2_1_1                     0.0  4.0   0.0        0.0
Test2_2_1                     3.0  0.0   0.0        0.0
religion.christian_20674_1_1  0.0  0.0   1.0        0.0
religion.christian_20674_2_1  0.0  0.0   0.0        1.0
religion.christian_20674_3_1  0.0  1.0   0.0        0.0

Если вы действительно хотите массив Numpy, вы можете легко преобразовать фрейм данных:

arr = df.values
print(arr)

Вывод:

[[0. 4. 0. 0.]
 [3. 0. 0. 0.]
 [0. 0. 1. 0.]
 [0. 0. 0. 1.]
 [0. 1. 0. 0.]]

Вы можетевместо этого также преобразуйте фрейм данных в структурированный массив , что позволит вам сохранить метки строк и столбцов:

arr = df.to_records()
print(arr.dtype.names)
print(arr)

Вывод:

('index', 'bye', 'hi', 'path', 'religious')
[('Test2_1_1', 0., 4., 0., 0.)
 ('Test2_2_1', 3., 0., 0., 0.)
 ('religion.christian_20674_1_1', 0., 0., 1., 0.)
 ('religion.christian_20674_2_1', 0., 0., 0., 1.)
 ('religion.christian_20674_3_1', 0., 1., 0., 0.)]

Редактировать: объяснениеsplitsubdicts

Вложенное понимание словаря, использованное в splitsubdicts, может показаться запутанным.На самом деле это просто сокращение для написания вложенных циклов.Вы можете расширить понимание за несколько циклов for следующим образом:

def splitsubdicts(d):
    ret = {}

    for k0,v0 in d.items():
        for i,(k1,v1) in enumerate(v0.items()):
            ret['{}_{}'.format(k0, i + 1)] = {k1: v1}

    return ret

Значения, возвращаемые этой версией splitsubdicts, основанной на циклах, будут идентичны значениям, возвращаемым основанной на пониманииверсия выше.Основанная на понимании версия может быть немного быстрее , чем основанная на циклах версия, но на практике это не та вещь, о которой следует беспокоиться.

0 голосов
/ 25 ноября 2018

Используя библиотеку панд, вы можете легко превратить ваш словарь в матрицу.

Код:

import pandas as pd

d = {'test2':{'hi':4,'bye':3}, 'religion.christian_20674': {'path': 1, 'religious': 1, 'hi':1}}
df = pd.DataFrame(d).T.fillna(0)

print(df)

Вывод:

                          bye   hi  path  religious
test2                     3.0  4.0   0.0        0.0
religion.christian_20674  0.0  1.0   1.0        1.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...