Numpy: 楕円を使用したインデックス作成の動作は直感的ではありません。

作成日 2020年07月27日  ·  6コメント  ·  ソース: numpy/numpy

省略記号を使用した配列のインデックス作成は、非常に直感に反する場合があります。 たとえば、次の例では、冗長な楕円を導入すると、出力の形状が変わります。

a = np.array([[[False]]])
a[0:0, 0, ..., [0]]
Out[23]: array([], shape=(1, 0), dtype=bool)
a[0:0, 0,  [0]]
Out[24]: array([], shape=(0, 1), dtype=bool)

これは望ましい動作ではないと思いますが、複雑なインデックス作成の処理方法に関する設計上の決定に直接起因しているようです。

Numpy / Pythonのバージョン情報:

1.17.3 3.7.5(デフォルト、2019年10月25日、10:52:18)
[Clang 4.0.1(tags / RELEASE_401 / final)]

04 - Documentation 33 - Question 57 - Close?

最も参考になるコメント

私はこれがすべて混乱していることに同意します、そして私はここで何が起こっているのかをチェックしなければ確信さえしなかったでしょう。 しかし、それは私には正しい選択のように思えます。

なぜそれは本当に「見えない」べきなのでしょうか? ...は、任意の数の次元で同じように動作する必要があります。 そのためには、すべての場合に転置をトリガーする必要があります。 つまり、 series, ..., colorとして編成されたものを想像してください。ここで、 ...はユーザー定義であり、0-dにすることができます。 そのデータを処理するプログラムを作成する場合、 ...が何に展開されるか(または展開されないか)に関係なく、インデックスを予測どおりに転置する必要があります。

結局、これは単に紛らわしいので、それを解決するには、 .oindex.vindexなどをもっと真剣に取り上げる必要があります//numpy.org/neps/nep- 0021-advanced-indexing.html

全てのコメント6件

これは特に厄介なコーナーケースのように見えます- ...は、2つの高度なインデックス0[0]非隣接と見なすように強制していると考えていますが、それらがインデックスを付ける軸は隣接しています。

numpyインデックスを複製しようとしたときに、この問題が発生しました。 これは2つのルール間の奇妙な相互作用だと思います。

  • 省略記号は、完全なスライスのタプルに展開されます。各スライスは、基本的なインデックスと見なされます。
  • 混合次数の高度なインデックスと基本的なインデックスは、転置操作をトリガーします。

この特殊なケースがトリガーされるのは、0-dタプル(...がすべてのインデックスが存在する状態で使用されている場合)が、実際には見えないはずの基本的なインデックスブロックと見なされるためです。

私はこれがすべて混乱していることに同意します、そして私はここで何が起こっているのかをチェックしなければ確信さえしなかったでしょう。 しかし、それは私には正しい選択のように思えます。

なぜそれは本当に「見えない」べきなのでしょうか? ...は、任意の数の次元で同じように動作する必要があります。 そのためには、すべての場合に転置をトリガーする必要があります。 つまり、 series, ..., colorとして編成されたものを想像してください。ここで、 ...はユーザー定義であり、0-dにすることができます。 そのデータを処理するプログラムを作成する場合、 ...が何に展開されるか(または展開されないか)に関係なく、インデックスを予測どおりに転置する必要があります。

結局、これは単に紛らわしいので、それを解決するには、 .oindex.vindexなどをもっと真剣に取り上げる必要があります//numpy.org/neps/nep- 0021-advanced-indexing.html

私は、現在の振る舞いが最良の一般化であるという@sebergの主張に

私はその提案について知りませんでした、参照@sebergに感謝します!

私があなたの議論を理解していることを確認するために言い換えさせてください。 高度なインデックスAと基本的なインデックスBにラベルを付け、上記のように並べ替え操作を(一般化された)転置と呼んでいるとします。 あなたの例では、4つのケースがあります。

  • [A1, ..., A2]および[B1, ... A1] :これらのケースは、 ...展開方法に関係なく、 [A1, A2, ....]および[A1, B1, ...]への転置をトリガーします。
  • [A1, ..., B1]および[B1, ..., B2] :これらの場合はそうではありません。

...展開方法に関係なく、 seriescolorがどのクラス(AまたはB)に属するかがわかれば、これらのルールは一貫しています。 これは、 ...を基本インデックスの(潜在的に0-d)ブロックとして扱うことと同じです。 0-d ...を特別な場合として扱うのは、ユーザーが2D配列を渡すか3D以上を渡すかによって転置が条件となるためです。 私は同意します、これは悪い場所です。

0-dブロックはno-opである必要があるという私の直感は、タプルがどのように動作するかによって決まりました。ここで、 i場合、

i: int
M: Tuple[int, ...]
N = ()
assert M[:i] + N + M[i:] == M

これはnumpyインデックス付け規則と矛盾し、 iが何であるかに応じて上記の4つのケースになります。 これは、 ...処理方法ではなく、転置操作自体と関係があり、NEP21提案の議論です。

開発中に、インデックス作成の方法を切り替え、コードの将来性を保証するために...を挿入し、形状が魔法のように転置されたときに本当に混乱しました。 空の...ケースが特に直感に反しているため、悪化しました。

ご覧いただきありがとうございます! よろしければ、ドキュメントPRを提出できます。

@antonl a

このページは役に立ちましたか?
0 / 5 - 0 評価