добавление массивов, хранящихся в диктантах, в один диктант на python

#python #numpy #dictionary

Вопрос:

У меня есть массив диктов с одинаковыми ключами, и для каждого ключа у меня есть массив значений, как показано в примере ниже:

 dict_arr = np.array([{'x': np.array([1,2,3]), 'y': np.array([1,4,9])}, {'x': np.array([4,5,6]), 'y': np.array([16,25,64])}])  

Что мне нужно сделать, так это объединить все в один диктант, но под слиянием я подразумеваю, что я должен объединить значения массивов из одного и того же ключа. Ожидаемым результатом для примера будет:

 {'x': array([1., 2., 3., 4., 5., 6.]), 'y': array([ 1., 4., 9., 16., 25., 64.])}  

Код, который я сделал, был следующим:

 new_dict = {'x': np.array([]), 'y': np.array([])} for dict_ in dict_arr:  for key, value in dict_.items():  new_dict[key] = np.append(new_dict[key], value) print(new_dict)  

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

Примечание: мой реальный массив предсказывает порождается сбора данных борту, которые не могут приобрести более 1024 сведения на канал, поэтому каждый словарь в списке, кроме последнего, имеет от одного до трех матриц с разрешением 1024 плавает ценности каждого, и число предсказывает я обычно составляет порядка 400 тысяч.

Комментарии:

1. массивы numpy на самом деле не предназначены для такого рода структуры данных. И зацикливание звучит как ваш лучший вариант…

2. Я также должен отметить, что dict_array это то, что не имеет смысла. Размещение объектов Python в a numpy.ndarray в основном создает менее эффективный список Python. Что бы я сделал, если данные могут быть огромными, так это использовал список, чтобы у вас было что-то вроде {'x':[...], ...} того, чтобы вы могли эффективно расширять этот список, а затем, наконец, преобразовать его в массив numpy внутренне, если необходимо. Потому np.append(new_dict[key], value) что в цикле есть анти-шаблон

3. В любом случае, нет способа сделать то, что вы хотите, без итерации

Ответ №1:

Добавление списка выполняется быстрее, чем повторение np.append :

 In [44]: dict_arr = np.array([{'x': np.array([1,2,3]), 'y': np.array([1,4,9])}, {'x': np.array([4,5,6]), 'y': np  ...: .array([16,25,64])}]) In [45]: new_dict={'x':[], 'y':[]} In [46]: for dict in dict_arr:  ...: for key,value in dict.items():  ...: new_dict[key].append(value)  ...:  In [47]: new_dict Out[47]:  {'x': [array([1, 2, 3]), array([4, 5, 6])],  'y': [array([1, 4, 9]), array([16, 25, 64])]} In [48]: newer = {key:np.hstack(value) for key,value in new_dict.items()} In [49]: newer Out[49]: {'x': array([1, 2, 3, 4, 5, 6]), 'y': array([ 1, 4, 9, 16, 25, 64])}  

defaultdict может упростить создание такого рода словарей:

 In [55]: from collections import defaultdict In [56]: dd = defaultdict(list) In [58]: for dict in dict_arr:  ...: for k,v in dict.items():  ...: dd[k].append(v)  ...:  In [59]: dd Out[59]:  defaultdict(list,  {'x': [array([1, 2, 3]), array([4, 5, 6])],  'y': [array([1, 4, 9]), array([16, 25, 64])]}) In [60]: newer = {key:np.hstack(value) for key,value in dd.items()} In [61]: newer Out[61]: {'x': array([1, 2, 3, 4, 5, 6]), 'y': array([ 1, 4, 9, 16, 25, 64])}  

Поскольку ключи одинаковы, мы можем использовать values :

 In [54]: list(zip(*[list(dict.values()) for dict in dict_arr])) Out[54]: [(array([1, 2, 3]), array([4, 5, 6])), (array([1, 4, 9]), array([16, 25, 64]))]  

и подтверждаю:

 In [63]: [np.hstack(i) for i in zip(*[list(dict.values()) for dict in dict_arr])] Out[63]: [array([1, 2, 3, 4, 5, 6]), array([ 1, 4, 9, 16, 25, 64])]  

Это все еще нужно вернуть в dict форму

 In [67]: {k:v for k,v in zip(dict_arr[0], Out[63])} Out[67]: {'x': array([1, 2, 3, 4, 5, 6]), 'y': array([ 1, 4, 9, 16, 25, 64])}  

Ответ №2:

Я не уверен на 100%, что это будет более эффективно для вашего варианта использования (на самом деле, есть большая вероятность, что это будет медленнее, так как мы все еще зацикливаемся…), но я рекомендую попробовать и рассчитать время на ваших полных данных:

 import pandas as pd import numpy as np  dict_arr = np.array([{'x': np.array([1,2,3]), 'y': np.array([1,4,9])}, {'x': np.array([4,5,6]), 'y': np.array([16,25,64])}])  df = pd.DataFrame.from_records(dict_arr) df.apply(np.hstack, result_type='reduce').to_dict()  # {'x': array([1, 2, 3, 4, 5, 6]), 'y': array([ 1, 4, 9, 16, 25, 64])}