2013-03-22 8 views
24

मेरे पास एक शब्दकोश है जिसे मुझे NumPy संरचित सरणी में कनवर्ट करने की आवश्यकता है। मैं arcpy function NumPyArraytoTable का उपयोग कर रहा हूं, इसलिए एक NumPy संरचित सरणी एकमात्र डेटा प्रारूप है जो काम करेगा।पाइथन dict num numpy संरचित सरणी

इस सूत्र के आधार पर: Writing to numpy array from dictionary और इस सूत्र: How to convert Python dictionary object to numpy array

मैं कोशिश की है इस:

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) 

उत्तर

44

आप 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')]) 

आप tuples, 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) 

काम करने के बहुत करीब था। यदि आप को tuple (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 व्यवहार करता है tuples की तुलना में अलग सूचियां: Robert Kern explains:

एक नियम के रूप में माना जाता है tuples "अदिश" रिकॉर्ड और सूचियाँ हैं पर recursed। यह नियम numpy.array() को समझता है कि अनुक्रम रिकॉर्ड हैं और कौन से अन्य अनुक्रमों को पर रिकर्स किया जाना है; अर्थात।कौन सा अनुक्रम एक और आयाम बनाता है और परमाणु तत्व हैं।

(0.0, 1.1181753789488595) चूंकि वे परमाणु तत्वों में से एक माना जाता है, यह एक टपल, नहीं एक सूची होना चाहिए।

+0

मैं आपके इस सवाल का जवाब करने के लिए भेजा कुछ ऐसा करने के लिए और यह काम नहीं कर रहा है। इस पर कुछ दिन बिताएं। क्या आप मदद कर सकेंगे? http://stackoverflow.com/questions/32723802/scipy-and-preserving-mat-file-mat-matlab-data-file- संरचना – Raaj

+0

एक सीधी प्रतिलिपि और पेस्ट कोड नमूना त्रुटि देता है। मैंने 'result.items()' to 'list (result.items()) को बदलकर इसे ठीक किया है। पायथन 3.5 – Atlas7

+1

@ एटलस 7: हेड-अप के लिए धन्यवाद। Python3 के लिए उत्तर अद्यतन किया गया है। – unutbu

2

मुझे एक बेहतर विधि का प्रस्ताव जब dictionnary के मूल्यों में एक ही लंबाई के साथ सूची रहे हैं दो:

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 
2

मैं अलग सरणियों पर कुंजी और मूल्यों के भंडारण पसंद करेंगे। यह मैं अक्सर अधिक व्यावहारिक। सरणी के ढांचे संरचनाओं की सरणी के लिए सही प्रतिस्थापन हैं। अधिकांश समय के रूप में आपको केवल अपने डेटा का एक सबसेट संसाधित करना पड़ता है (इस मामले में कुंजी या मान, केवल दो सरणी में से केवल एक के साथ ऑपरेशन एक साथ दो सरणी के आधे से परिचालन करने से अधिक कुशल होगा।

लेकिन मामले में इस तरह से संभव नहीं है, मैं कॉलम के आधार के बजाय पंक्ति के अनुसार क्रमबद्ध सरणियों उपयोग करने के लिए सुझाव है। इस तरह आप दो सरणियों होने के रूप में एक ही लाभ होता है, लेकिन एक में केवल पैक।

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)} 
2

ई ven अधिक सरल आप पांडा का उपयोग कर स्वीकार करता है, तो:

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 
संबंधित मुद्दे