web-dev-qa-db-ja.com

python dict to numpy構造化配列

NumPy構造化配列に変換する必要がある辞書があります。私はarcpy関数 NumPyArraytoTable を使用しているので、NumPy構造化配列のみが機能するデータ形式です。

このスレッドに基づいて: 辞書からnumpy配列に書き込む そしてこのスレッド: 変換方法Python辞書オブジェクトを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)
31
Christa

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]_を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_はリストをタプルとは異なる扱います: ロバート・カーンは説明します

原則として、タプルは「スカラー」レコードと見なされ、リストは再帰されます。この規則は、numpy.array()がどのシーケンスがレコードであり、どのシーケンスが再帰されるかを判断するのに役立ちます。すなわち、どのシーケンスが別の次元を作成し、どのシーケンスがアトミック要素であるか。

_(0.0, 1.1181753789488595)_はこれらのアトミック要素の1つと見なされるため、リストではなくタプルにする必要があります。

50
unutbu

辞書の値が同じ長さのリストである場合の改善された方法を提案しましょう:

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
dgdm

pandasを使用して受け入れる場合はさらに簡単です:

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
2
dgdm

キーと値を別々の配列に保存することをお勧めします。これは、しばしばより実用的です。配列の構造は、構造の配列に完全に置き換わるものです。ほとんどの場合、データのサブセットのみを処理する必要があります(この場合、キーまたは値は、2つのアレイの半分のみを操作するよりも、2つのアレイのうち1つのみを操作する方が効率的です。

しかし、この方法が不可能な場合は、行ではなく列でソートされた配列を使用することをお勧めします。この方法では、2つの配列を持つのと同じ利点がありますが、1つだけにパックされます。

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)}
1
Federico Ressi

承認済みの回答と同様。辞書キーから配列を作成する場合:

np.array( Tuple(dict.keys()) )

辞書の値から配列を作成する場合:

np.array( Tuple(dict.values()) )