11

numpy で 1 次元配列を作成し、文字列 (数字を含む) を使用してインデックスを作成すると、予想どおりエラーが発生します。

>>> import numpy as np
>>> a = np.arange(15)
>>> a['10']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: field named 10 not found.

ただし、2 次元配列を作成し、インデックスに 2 つの文字列を使用すると、エラーは発生せず、文字列が最初に整数に変換されたかのように要素を返します。

>>> b = np.arange(15).reshape(3,5)
>>> b
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
>>> b[1, 2]
7
>>> b['1', '2']
7

どうしたの?2 次元の場合にエラーが発生しないのはなぜですか?

4

2 に答える 2

2

免責事項-- この回答は不完全なものです

あなたが見ているのは、派手なシーケンスインデックスの結果だと思います。文字列は実際にはシーケンスであるため、一度に 1 文字ずつ文字列の値を取得し、それらを " intp" オブジェクト (おそらく Python のint関数を使用するだけ) に変換します。これにより、配列インデックスが得られます。

これは、1D の場合も説明します。

class Foo(object):
    def __getitem__(self,idx):
        print idx

a = Foo()
a[12]
a[12,12]

tuple2 番目のケースでは aが渡されるのに対し、最初のケースでは整数が渡されることに注意してください。


私がまだ理解していないこの部分は、このテストによって実証されています。

import numpy as np
a = np.arange(156).reshape(13,12)
print a[12,3] == a['12',3]   #True -- I would have thought False for this one...
print a['12',3] == a[('1','2'),3]  #False -- I would have guessed True for this..
assert( a[tuple('12'),3] == a[(1,2),3] )  #This passes, as expected

コメントでこれを説明してみてください。intp:) 不一致は、レコード配列をよりスムーズに処理するために、一連のオブジェクトに変換するときに、numpy が意図的に文字列をそのままにしている可能性があります...

于 2012-10-31T13:15:49.513 に答える
1

追加するために、最初のケース (単一の文字列) は、おそらく文字列をフィールド名として使用する再配列のサポートに関係していることに注意してください。

2 番目のケースに依存しないでください。Numpy は、非配列のインデックス付けについて非常に自由です。非配列 (およびスライスでも None でもない) の場合、これらの文字列に対して明確に定義されている整数配列に変換しようとするだけだからです。ただし、これは設計によるものではありません。これは、実際に変更するためにこの動作に (少なくとも部分的に) 依存しているソフトウェアが多すぎるためです。文字列用。


@mgilsonの詳細。これらすべてが適応外の使用法であることを考えると、実際には実装の詳細にまで及びます。たとえば、単一の文字列は現在、再配列でなくても再配列の特殊なケースですが、文字列のタプルは再配列の特殊なケースのみです。

文字列のリストは、タプルではなく、ほとんどの場合、タプルのように動作するため、多少特殊なケースになっています。これは小さなバグかもしれません...その中にシーケンスが見つかるため、派手なインデックス作成をトリガーしますが、それを配列に変換することを「忘れます」。私は通常、タプルを使用して複数の軸を表します。

于 2012-10-31T14:05:13.303 に答える