11

次のように要素にアクセスできるという意味で、collections.namedtuple と非常によく似た動作をする NumPy オブジェクトを作成することは可能ですか。

data[1] = 42
data['start date'] = '2011-09-20'  # Slight generalization of what is possible with a namedtuple

複雑なデータ型を使用しようとしました:

>>> data = numpy.empty(shape=tuple(), dtype=[('start date', 'S11'), ('n', int)])

これにより、namedtuple 型のような 0 次元の値が作成されます。それはほとんど動作します:

>>> data['start date'] = '2011-09-20'
>>> data
array(('2011-09-20', -3241474627884561860), 
      dtype=[('start date', '|S11'), ('n', '<i8')])

ただし、「配列」は 0 次元であるため、要素へのアクセスは機能しません。

>>> data[0] = '2011-09-20'
Traceback (most recent call last):
  File "<ipython-input-19-ed41131430b9>", line 1, in <module>
    data[0] = '2011-09-20'
IndexError: 0-d arrays can't be indexed.

上記の目的の動作 (文字列とインデックスの両方によるアイテムの割り当て) を NumPy オブジェクトで取得する方法はありますか?

4

4 に答える 4

3

numpy.recモジュールを使用すると、このようなことができます。必要なのはrecordこのモジュールのクラスですが、そのようなクラスのインスタンスを直接作成する方法がわかりません。recarray間接的な方法の 1 つは、最初に単一のエントリで を作成することです。

>>> a = numpy.recarray(1, names=["start date", "n"], formats=["S11", "i4"])[0]
>>> a[0] = "2011-09-20"
>>> a[1] = 42
>>> a
('2011-09-20', 42)
>>> a["start date"]
'2011-09-20'
>>> a.n
42

のインスタンスを直接作成する方法がわかった場合はrecord、お知らせください。

于 2011-09-20T19:07:37.437 に答える
3

これは、 Pandasパッケージの「シリーズ」によって適切に実装されています。

たとえば、チュートリアルから:

>>> from pandas import *
>>> import numpy as np
>>> s = Series(np.random.randn(5), index=['a', 'b', 'c', 'd', 'e'])
>>> s
a    -0.125628696947
b    0.0942011098937
c    -0.71375003803
d    -0.590085433392
e    0.993157363933
>>> s[1]
0.094201109893723267
>>> s['b']
0.094201109893723267

数日間これで遊んでいますが、提供できるものがたくさんあるようです。

于 2011-09-21T03:24:23.313 に答える
2

OK、私は解決策を見つけました、しかし私はもっとエレガントなものを見たいです:

data = numpy.empty(shape=1, dtype=[('start date', 'S11'), ('n', int)])[0]

単一の要素で1次元配列を作成し、要素を取得します。これにより、要素へのアクセスが文字列と数値インデックスの両方で機能するようになります。

>>> data['start date'] = '2011-09-20'  # Contains a space: more flexible than a namedtuple!
>>> data[1] = 123
>>> data
('2011-09-20', 123)

data最初に1つの要素で配列を作成し、この要素を抽出することなく、を直接構築する方法があれば便利です。以来

>>> type(data)
<type 'numpy.void'>

NumPyコンストラクターを何と呼ぶことができるかわかりません…(のdocstringはありませんnumpy.void)。

于 2011-09-20T19:07:16.200 に答える
2

(質問への回答をより具体的にするためにEOLが推奨するように編集されました。)

0-dim 配列を作成します (スカラー コンストラクターも見つかりませんでした。)

>>> data0 = np.array(('2011-09-20', 0), dtype=[('start date', 'S11'), ('n', int)])
>>> data0.ndim
0

0-dim 配列の要素にアクセスする

>>> type(data0[()])
<class 'numpy.void'>
>>> data0[()][0]
b'2011-09-20'
>>> data0[()]['start date']
b'2011-09-20'

>>> #There is also an item() method, which however returns the element as python type
>>> type(data0.item())
<class 'tuple'>

構造化配列 (または再配列) をタプルのリストまたは配列と考えるのが最も簡単だと思います。インデックスは、列を選択する名前と行を選択する整数によって機能します。

>>> tupleli = [('2011-09-2%s' % i, i) for i in range(5)]
>>> tupleli
[('2011-09-20', 0), ('2011-09-21', 1), ('2011-09-22', 2), ('2011-09-23', 3), ('2011-09-24', 4)]
>>> dt = dtype=[('start date', '|S11'), ('n', np.int64)]
>>> dt
[('start date', '|S11'), ('n', <class 'numpy.int64'>)]

ゼロ次元配列、要素はタプル、つまり 1 つのレコード、変更された: スカラー要素ではありません。最後を参照してください

>>> data1 = np.array(tupleli[0], dtype=dt)
>>> data1.shape
()
>>> data1['start date']
array(b'2011-09-20', 
      dtype='|S11')
>>> data1['n']
array(0, dtype=int64)

要素が 1 つの配列

>>> data2 = np.array([tupleli[0]], dtype=dt)
>>> data2.shape
(1,)
>>> data2[0]
(b'2011-09-20', 0)

1次元配列

>>> data3 = np.array(tupleli, dtype=dt)
>>> data3.shape
(5,)
>>> data3[2]
(b'2011-09-22', 2)
>>> data3['start date']
array([b'2011-09-20', b'2011-09-21', b'2011-09-22', b'2011-09-23',
       b'2011-09-24'], 
      dtype='|S11')
>>> data3['n']
array([0, 1, 2, 3, 4], dtype=int64)

EOLの例と同じように、単一のレコードへの直接インデックス付けが機能することを知りませんでした

>>> data3[2][1]
2
>>> data3[2][0]
b'2011-09-22'

>>> data3[2]['n']
2
>>> data3[2]['start date']
b'2011-09-22'

EOLの例を理解しようとしている:スカラー要素と0次元配列は違う

>>> type(data1)
<class 'numpy.ndarray'>
>>> type(data1[()])   #get element out of 0-dim array
<class 'numpy.void'>

>>> data1[0]
Traceback (most recent call last):
  File "<pyshell#98>", line 1, in <module>
    data1[0]
IndexError: 0-d arrays can't be indexed
>>> data1[()][0]
b'2011-09-20'

>>> data1.ndim
0
>>> data1[()].ndim
0

(注: 偶然、開いている python 3.2 インタープリターで例を入力したため、b'...' があります)

于 2011-09-23T02:03:33.157 に答える