Создание словаря из трехмерного массива с помощью Python - PullRequest
0 голосов
/ 08 мая 2018

В настоящее время у меня проблема с сортировкой данных трехмерного массива в разные словари на основе первого столбца массива. Я хочу проверить первый столбец массива и сделать словарь с именами строк в нем. Я также хотел бы сделать двумерный массив со значениями в той же строке. Мои данные выглядят примерно так:

allValues=[["str1","str1","str1","str1","str1","str1","str1","str2","str2","str2","str2","str2"],[1,2,3,4,5,6,7,8,9,10,11,12],[1,2,3,4,5,6,7,8,9,10,11,12]] 

И моя цель:

allValuesDict = {'str1': [[1,2,3,4,5,6,7], [1,2,3,4,5,6,7]], 'str2': [[8,9,10,11,12], [8,9,10,11,12]]}

Ответы [ 4 ]

0 голосов
/ 08 мая 2018

Панды - хороший инструмент для этого. Выдает достаточно читаемый код.

>>> import pandas as pd

>>> df = pd.DataFrame(allValues).T
>>> df
       0   1   2
0   str1   1   1
1   str1   2   2
2   str1   3   3
3   str1   4   4
4   str1   5   5
5   str1   6   6
6   str1   7   7
7   str2   8   8
8   str2   9   9
9   str2  10  10
10  str2  11  11
11  str2  12  12

>>> grouped = df.groupby(0)[[1,2]].apply(lambda l: list(zip(*pd.Series.tolist(l))))
>>> grouped
0
str1    [(1, 2, 3, 4, 5, 6, 7), (1, 2, 3, 4, 5, 6, 7)]
str2          [(8, 9, 10, 11, 12), (8, 9, 10, 11, 12)]
dtype: object

>>> grouped.to_dict()
{'str1': [(1, 2, 3, 4, 5, 6, 7), (1, 2, 3, 4, 5, 6, 7)], 'str2': [(8, 9, 10, 11, 12), (8, 9, 10, 11, 12)]}
0 голосов
/ 08 мая 2018

Вы можете использовать collections.defaultdict для решения O (n).

Обратите внимание, что очень специфично для структуры данных, которая у вас есть:

from collections import defaultdict

d = defaultdict(lambda: [[], []])

for i, j, k in zip(*allValues):
    d[i][0].append(j)
    d[i][1].append(k)

Если вам нужно конвертировать в обычный dict:

res = dict(d)

print(res)

{'str1': [[1, 2, 3, 4, 5, 6, 7], [1, 2, 3, 4, 5, 6, 7]],
 'str2': [[8, 9, 10, 11, 12], [8, 9, 10, 11, 12]]}
0 голосов
/ 08 мая 2018

zip может перевести ваш список в [['str1',1,1],['str2',2,2],...], что может упростить итерации:

allValues = [['str1','str1','str1','str1','str1','str1','str1','str2','str2','str2','str2','str2'],
             [1,2,3,4,5,6,7,8,9,10,11,12],
             [1,2,3,4,5,6,7,8,9,10,11,12]]

D = {}
for k,v1,v2 in zip(*allValues):
    if k in D:
        D[k][0].append(v1)
        D[k][1].append(v2)
    else:
        D[k] = [[v1],[v2]]

print D

Выход:

{'str2': [[8, 9, 10, 11, 12], [8, 9, 10, 11, 12]], 'str1': [[1, 2, 3, 4, 5, 6, 7], [1, 2, 3, 4, 5, 6, 7]]}

Использование defaultdict может еще больше упростить это:

from collections import defaultdict

allValues = [['str1','str1','str1','str1','str1','str1','str1','str2','str2','str2','str2','str2'],
             [1,2,3,4,5,6,7,8,9,10,11,12],
             [1,2,3,4,5,6,7,8,9,10,11,12]]

D = defaultdict(lambda:[[],[]])
for k,v1,v2 in zip(*allValues):
    D[k][0].append(v1)
    D[k][1].append(v2)

print D
print dict(D)  # If you don't want the final type to be defaultdict.

Выход:

defaultdict(<function <lambda> at 0x00000000070A5128>, {'str2': [[8, 9, 10, 11, 12], [8, 9, 10, 11, 12]], 'str1': [[1, 2, 3, 4, 5, 6, 7], [1, 2, 3, 4, 5, 6, 7]]})
{'str2': [[8, 9, 10, 11, 12], [8, 9, 10, 11, 12]], 'str1': [[1, 2, 3, 4, 5, 6, 7], [1, 2, 3, 4, 5, 6, 7]]}
0 голосов
/ 08 мая 2018

Вы можете использовать itertools.groupby и zip:

import itertools
allValues=[["str1","str1","str1","str1","str1","str1","str1","str2","str2","str2","str2","str2"],[1,2,3,4,5,6,7,8,9,10,11,12],[1,2,3,4,5,6,7,8,9,10,11,12]] 
main, *rest = allValues
grouped_data = list(itertools.chain.from_iterable([[[a, [h for _, h in b]] for a, b in itertools.groupby(zip(main, i), key=lambda x:x[0])] for i in rest]))
final_grouping = {a:[i for _, i in b] for a, b in itertools.groupby(sorted(grouped_data, key=lambda x:x[0]), key=lambda x:x[0])}

Выход:

{'str1': [[1, 2, 3, 4, 5, 6, 7], [1, 2, 3, 4, 5, 6, 7]], 'str2': [[8, 9, 10, 11, 12], [8, 9, 10, 11, 12]]}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...