web-dev-qa-db-ja.com

Numpyの0d配列がスカラーと見なされないのはなぜですか?

確かに0d配列はスカラーですが、Numpyはそうは思わないようです...何かが足りないのか、それとも概念を誤解しているだけなのでしょうか?

>>> foo = numpy.array(1.11111111111, numpy.float64)
>>> numpy.ndim(foo)
0
>>> numpy.isscalar(foo)
False
>>> foo.item()
1.11111111111
62
Salim Fadhley

それについてあまり考えすぎてはいけません。最終的には、個人のメンタルヘルスと長寿にとってより優れています。

Numpyのスカラー型の奇妙な状況は、1x1マトリックスをスカラー型に分解するための優雅で一貫した方法がないという事実から生まれました。数学的には同じものですが、非常に異なるコードで処理されます。

科学的なコードを大量に実行している場合、最終的にはmax(a)などのものがすべてのサイズの行列(スカラーを含む)でも機能するようになります。数学的には、これはまったく理にかなったことです。ただし、プログラマにとってこれは、Numpyでスカラーを提示するものはすべて.shapeおよび.ndim属性を持つ必要があることを意味します。そのため、少なくともufuncは、Numpyで21の可能なスカラー型の入力に対して明示的な型チェックを行う必要はありません。

一方、これらは既存のPythonライブラリーdoesがスカラー型に対して明示的な型チェックを行う)でも機能する必要があります。これはNumpy ndarrayが持っているのでジレンマですそれらがスカラーに減らされたときにタイプを個別に変更し、すべてのアクセスをチェックせずにそれが発生したかどうかを知る方法はありません。実際にそのルートをたどると、スカラーによる作業が途方もなく遅くなるでしょうタイプ標準。

Numpy開発者の解決策は、ndarrayとPythonの両方のスカラーから独自のスカラー型を継承することです。これにより、すべてのスカラーが.shape、.ndim、.Tなどにもなります。1x1マトリックスはまだそこにありますが、スカラーを処理することがわかっている場合は、その使用はお勧めしません。これは理論的には正常に機能するはずですが、ペイントローラーで見落としていた場所が見られることがあります。見るためにすべてに公開:

_>>> from numpy import *
>>> a = array(1)
>>> b = int_(1)
>>> a.ndim
0
>>> b.ndim
0
>>> a[...]
array(1)
>>> a[()]
1
>>> b[...]
array(1)
>>> b[()]
1
_

_a[...]_とa[()]が異なるものを返す必要がある理由は実際にはありませんが、そうします。これを変更する提案がありますが、1x1アレイのジョブを完了するのを忘れているようです。

潜在的に大きく、おそらく解決できない問題は、Numpyスカラーが不変であるという事実です。したがって、スカラーをndarrayに「スプレー」すること、数学的には配列をスカラーに縮小する随伴操作は、実装するPITAです。 Numpyスカラーを実際に拡張することはできません。newaxisが不思議なことに機能しても、定義上、ndarrayにキャストすることはできません。

_>>> b[0,1,2,3] = 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'numpy.int32' object does not support item assignment
>>> b[newaxis]
array([1])
_

Matlabでは、スカラーのサイズを大きくすることは、完全に許容できる頭のない操作です。 Numpyでは、どこにでもa = array(a)を使用する必要がありますthinkスカラーで始まり、配列で終わる可能性があります。 NumpyがPythonでNiceをプレイするためにこのようにならなければならない理由を理解していますが、それでも多くの新しいスイッチャーがこれについて深く混乱しているという事実は変わりません。一部の人はこの行動に苦労し、最終的には忍耐強いという明確な記憶を持っていますが、あまりに遠く離れている他の人は、通常、最も無邪気な夢に出没する深い無形の精神的な傷跡を残しています。それは皆にとって醜い状況です。

126
Tim Lin

スカラー配列を少し異なる方法で作成する必要があります。

>>> x = numpy.float64(1.111)
>>> x
1.111
>>> numpy.isscalar(x)
True
>>> numpy.ndim(x)
0

numpyのスカラー のように見えますが、純粋に数学的な観点から使用する場合とは少し異なる概念かもしれません。スカラー行列の観点から考えていると思いますか?

6
Jason Baker