в Python dict, чтобы включает в себя структурированный массив
У меня есть словарь, который мне нужно преобразовать в структурированный массив NumPy. Я использую функцию arcpy NumPyArraytoTable, таким образом, структурированный массив NumPy-это единственный формат данных, который будет работать.
На основе этого потока: запись в массив numpy из словаря и этот поток: как преобразовать объект Python dictionary в массив numpy
Я пробовал это:
result = {0: 1.1181753789488595, 1: 0.5566080288678394, 2: 0.4718269778030734, 3: 0.48716683119447185, 4: 1.0, 5: 0.1395076201641266, 6: 0.20941558441558442}
names = ['id','data']
formats = ['f8','f8']
dtype = dict(names = names, formats=formats)
array=numpy.array([[key,val] for (key,val) in result.iteritems()],dtype)
Но я продолжаю получать expected a readable buffer object
Метод ниже работает, но глуп и очевидно не будет работать для реальных данных. Я знаю, что есть более изящный подход, я просто не могу понять его.
totable = numpy.array([[key,val] for (key,val) in result.iteritems()])
array=numpy.array([(totable[0,0],totable[0,1]),(totable[1,0],totable[1,1])],dtype)
4 ответов:
Можно использовать
np.array(list(result.items()), dtype=dtype):import numpy as np result = {0: 1.1181753789488595, 1: 0.5566080288678394, 2: 0.4718269778030734, 3: 0.48716683119447185, 4: 1.0, 5: 0.1395076201641266, 6: 0.20941558441558442} names = ['id','data'] formats = ['f8','f8'] dtype = dict(names = names, formats=formats) array = np.array(list(result.items()), dtype=dtype) print(repr(array))Урожайность
array([(0.0, 1.1181753789488595), (1.0, 0.5566080288678394), (2.0, 0.4718269778030734), (3.0, 0.48716683119447185), (4.0, 1.0), (5.0, 0.1395076201641266), (6.0, 0.20941558441558442)], dtype=[('id', '<f8'), ('data', '<f8')])
Если вы не хотите создавать промежуточный список кортежей,
list(result.items()), то вместо этого вы можете использоватьnp.fromiter:В Python2:
array = np.fromiter(result.iteritems(), dtype=dtype, count=len(result))В Python3:
array = np.fromiter(result.items(), dtype=dtype, count=len(result))
Почему использование списка
[key,val]не работает:Кстати, ваша попытка,
numpy.array([[key,val] for (key,val) in result.iteritems()],dtype)Был очень близок к работе. Если вы измените список
[key, val]на кортеж(key, val), то это сработало бы. Конечно,numpy.array([(key,val) for (key,val) in result.iteritems()], dtype)- это то же самое, что
numpy.array(result.items(), dtype)В Python2, или
numpy.array(list(result.items()), dtype)В Python3.
np.arrayотносится к спискам иначе, чем к кортежам: Роберт Керн объясняет :ПосколькуКак правило, кортежи считаются "скалярными" записями, а списки являются повторяется дальше. Это правило помогает numpy.array() выяснить, какие последовательности-это записи, а также другие последовательности, подлежащие рекурсии на; то есть какие последовательности создают другое измерение и которые являются то атомные элементы.
Считается одним из таких атомарных элементов, то это должен быть Кортеж, а не список.
Позвольте мне предложить улучшенный метод, когда значения словаря являются списками с одинаковой длиной:
import numpy def dctToNdarray (dd, szFormat = 'f8'): ''' Convert a 'rectangular' dictionnary to numpy NdArray entry dd : dictionnary (same len of list retrun data : numpy NdArray ''' names = dd.keys() firstKey = dd.keys()[0] formats = [szFormat]*len(names) dtype = dict(names = names, formats=formats) values = [tuple(dd[k][0] for k in dd.keys())] data = numpy.array(values, dtype=dtype) for i in range(1,len(dd[firstKey])) : values = [tuple(dd[k][i] for k in dd.keys())] data_tmp = numpy.array(values, dtype=dtype) data = numpy.concatenate((data,data_tmp)) return data dd = {'a':[1,2.05,25.48],'b':[2,1.07,9],'c':[3,3.01,6.14]} data = dctToNdarray(dd) print data.dtype.names print data
Еще проще, если вы принимаете использование панд:
import pandas result = {0: 1.1181753789488595, 1: 0.5566080288678394, 2: 0.4718269778030734, 3: 0.48716683119447185, 4: 1.0, 5: 0.1395076201641266, 6: 0.20941558441558442} df = pandas.DataFrame(result, index=[0]) print dfДает :
0 1 2 3 4 5 6 0 1.118175 0.556608 0.471827 0.487167 1 0.139508 0.209416
Я бы предпочел хранить ключи и значения в отдельных массивах. Это я часто практичнее. Структуры массивов являются идеальной заменой массиву структур. Поскольку большую часть времени вам приходится обрабатывать только подмножество ваших данных (в этом случае ключи или значения), работа только с одним из двух массивов будет более эффективной, чем работа с половиной из двух массивов вместе.
Но в случае, если этот способ невозможен, я бы предложил использовать массивы, отсортированные по столбцу, а не по ряд. Таким образом, вы получите то же преимущество, что и два массива, но упакованные только в один.
import numpy as np result = {0: 1.1181753789488595, 1: 0.5566080288678394, 2: 0.4718269778030734, 3: 0.48716683119447185, 4: 1.0, 5: 0.1395076201641266, 6: 0.20941558441558442} names = 0 values = 1 array = np.empty(shape=(2, len(result)), dtype=float) array[names] = r.keys() array[values] = r.values()Но мой любимый - это (проще):
import numpy as np result = {0: 1.1181753789488595, 1: 0.5566080288678394, 2: 0.4718269778030734, 3: 0.48716683119447185, 4: 1.0, 5: 0.1395076201641266, 6: 0.20941558441558442} arrays = {'names': np.array(k.keys(), dtype=float), 'values': np.array(k.values(), dtype=float)}
Comments