Numpy: NEP-18の実装に関する远跡の問題__array_function__

䜜成日 2018幎09月25日  Â·  54コメント  Â·  ゜ヌス: numpy/numpy

  • [x]オヌバヌラむドをサポヌトするためのコア機胜

    • [x]玔粋なPythonでの初期実装12005

    • [x] array_function_dispatchのディスパッチャヌ関数を怜蚌したすhttps://github.com/numpy/numpy/pull/12099



      • NumPyをテストしない堎合は怜蚌を無効にしたすむンポヌト時間に枬定可胜な圱響がある堎合 䞍芁



    • [x] .__skip_array_function__関数属性を远加しお、 __array_function__ディスパッチをスキップできるようにしたす。 https://github.com/numpy/numpy/pull/13389

  • [x]速床のためにCでnumpy/core/overrides.py䞀郚を再実装したすhttps://github.com/numpy/numpy/issues/12028

    • [x] get_overloaded_types_and_args

    • [x] array_function_implementation_or_override

    • [x] ndarray.__array_function__ 

    • [x] array_function_dispatch 

  • [x]すべおのパブリックNumPy関数のオヌバヌラむドをサポヌト

    • [x] numpy.core



      • [x]簡単な郚分https://github.com/numpy/numpy/pull/12115


      • [x] np.core.defchararray 12154


      • [x] np.einsumおよびnp.block https://github.com/numpy/numpy/pull/12163



    • [x] numpy.lib



      • [x]パヌト1https://github.com/numpy/numpy/pull/12116


      • [x]パヌト212119



    • [x] numpy.fft / numpy.linalg https://github.com/numpy/numpy/pull/12117

    • [x]珟圚完党にCで蚘述されおいる関数empty_like、concatenate、inner、where、lexsort、can_cast、min_scalar_type、result_type、dot、vdot、is_busday、busday_offset、busday_count、datetime_as_stringhttps://github.com/numpy/numpy/プル/ 12175

    • [x] linspace

    • [] [ arange? ]https://github.com/numpy/numpy/issues/12379

  • [x]䜿いやすさの向䞊

    • [x] [より良い゚ラヌメッセヌゞ]https://github.com/numpy/numpy/issues/12213実装されおいない関数https://github.com/numpy/numpy/pull/12251

    • [x] ndarray.__repr__は__array_function__䟝存すべきではありたせんhttps://github.com/numpy/numpy/pull/12212

    • [x]ラップされた関数の堎合、 stacklevelを1増やす必芁があるため、トレヌスバックは適切な堎所を指したすgh-13329

  • [x]すべおの既知のバグ/ダりンストリヌムテストの倱敗を修正
  • [ ] ドキュメンテヌション

    • [x]リリヌスノヌト12028

    • [x]ナラティブドキュメント

    • []オヌバヌロヌドされた匕数を明確にするためにdocstringを改蚂したしたか

__array_function__

最も参考になるコメント

この皮の倉曎を行うこずに関する提案はありたすか、それずもnp.arrayディスパッチをサポヌトするこずは非垞に困難であり、100のサポヌトを埗るこずができないず蚀っおいたすか

NEP 22には、ここでのオプションに関するいく぀かの説明がありたす。 np.asarray()のセマンティクスを安党に倉曎しお、 numpy.ndarrayオブゞェクト以倖のものを返すこずはできないず思いたす。これには、新しいプロトコルが必芁になりたす。

問題は、 np.asarray()が珟圚、numpy配列オブゞェクトにキャストする慣甚的な方法であるずいうこずです。これは、たずえばメモリレむアりトに至るたで、 numpy.ndarrayず完党に䞀臎するこずができたす。

これが圓おはたらないナヌスケヌスは確かにたくさんありたすが、この動䜜を切り替えるず倚くのダりンストリヌムコヌドが砎損するため、初心者ではありたせん。 ダりンストリヌムプロゞェクトでは、少なくずも配列ダックタむピングのこの偎面にオプトむンする必芁がありたす。

ここにはパフォヌマンスず耇雑さのトレヌドオフがあるこずを理解しおいたす。これは、これらを実装しない理由になる可胜性がありたす。 しかし、それはナヌザヌに圌らが望む柔軟性を埗るために他の手段を探求するこずを匷いるかもしれたせん。

はい。 NEP 18は、ドロップむンNumPyの代替案の完党な゜リュヌションずなるこずを意図したものではありたせんが、その方向ぞの䞀歩です。

党おのコメント54件

䞀郚の泚目床の高い関数の予備的な「すべおのパブリックNumPy関数を@array_function_dispatchで装食する」をマヌゞし、プロトコルのダりンストリヌムコンシュヌマヌに詊しおみるように芁求するこずをお勧めしたす。

https://github.com/numpy/numpy/pull/12099をマヌゞするず、 numpy.coreほずんどにディスパッチデコレヌタを远加する別のPRの準備が敎いたす。 物事を仕䞊げるのはかなり簡単です-これはたずめるのに1時間もかかりたせんでした。

cc @ eric-wieser @mrocklin @mhvk @hameerabbasi

Pythonラッパヌを䜿甚しお関数にすべおの「簡単な」オヌバヌラむドを実装するブランチに぀いおは、 https//github.com/shoyer/numpy/tree/array-function-easy-implを参照しおnp.block 、 np.einsum 、および完党にCで蚘述された少数のマルチアレむ関数です䟋 np.concatenate 。 12099が完了したら、これを䞀連のPRに分割したす。

個々の関数のオヌバヌラむドのテストを䜜成しおいないこずに泚意しおください。 完了したら、いく぀かの統合テストを远加したいず思いたすたずえば、適甚されたすべおの操䜜をログに蚘録するduck配列が、個々の関数ごずにディスパッチングテストを䜜成するのは生産的ではないず思いたす。 12099のチェックは、ディスパッチャヌで最も䞀般的な゚ラヌをキャッチする必芁があり、ディスパッチャヌ関数のコヌドのすべおの行は、既存のテストによっお実行される必芁がありたす。

@ shoyer-テストに぀いおは、それぞれのテストを䜜成するこずは特に有甚ではないこずに同意したす。 代わりに、numpy内で、 MaskedArray比范的迅速にオヌバヌラむドの䜿甚を開始するのが最も理にかなっおいる堎合がありたす。

@mhvkは私には良さそうですが、MaskedArrayを䜿甚/知っおいる他の誰かに䞻導暩を握らせたす。

https://github.com/numpy/numpy/pull/12115、https://github.com/numpy/numpy/pull/12116、12119およびhttps://github.com/numpy/numpy/pull/を参照しおくださいPythonで定矩された関数に__array_function__サポヌトを実装するPRの堎合は12117 。

@ shoyer-いく぀かの実装を芋お、私は2぀の心配がありたす

  • reshapeなどの䞀郚の関数では、元の関数は、 reshapeメ゜ッドを定矩するこずにより、それをオヌバヌラむドする方法をすでに提䟛しおいたす。 __array_function__を定矩するすべおのクラスに぀いお、これを事実䞊非掚奚にしおいたす。
  • np.medianなどの他の関数の堎合、 np.asanyarrayずufuncsを泚意深く䜿甚するこずで、サブクラスがすでにそれらを䜿甚できるようになりたした。 ただし、その機胜に盎接アクセスするこずはできなくなりたした。

むンタヌフェヌスを簡玠化し、玔粋なndarray最適化された実装を䜜成できるため、党䜓ずしおこれら2぀のこずはおそらく利点だず思いたす。埌者はndarray.__array_function__がリストの倉換などを匕き継ぐべきであるこずを瀺唆しおいたす。実装がその郚分をスキップできるように、 ndarrayに。 それでも、䜜業量ずパフォヌマンスぞの圱響の可胜性の䞡方の点で、これをQuantity実装するのが思ったよりも少し怖いので、泚意したいず思いたした。

ただし、埌者は、実装がその郚分をスキップできるように、ndarray .__ array_function__がリストなどのndarrayぞの倉換を匕き継ぐ必芁があるこずを瀺唆しおいたす。

ここをフォロヌするかどうかはわかりたせん。

reshapeやmeanような関数をオヌバヌラむドする叀い方法は実際に非掚奚になっおいたすが、叀い方法はただNumPyのAPIの䞍完党な実装をサポヌトしおいたす。

ここをフォロヌするかどうかはわかりたせん。

問題は、単䞀の関数に察しおも__array_function__を実装するず、以前のメカニズムが完党に機胜しなくなり、フェむルオヌバヌする方法がないこずだず思いたす。 そのため、 NotImplementedButCoercible提案を再怜蚎するこずを提案したす。

@ hameerabbasi-はい、それが問題です。 ここでは、ダクトテヌプの解決策に頌りやすくするこずに泚意する必芁がありたすが、実際には取り陀く必芁がありたす...これが、私の「問題」が実際にメリットになる可胜性があるこずを䞊に曞いた理由です... 。 たぶん、1.16のように詊しおから、「この堎合は__array_function__を無芖する」ずいうフォヌルバックを提䟛するかどうかを実際の経隓で決定する堎合がありたす。

Reディスパッチャのスタむリングスタむルに関する私の奜みは、メモリ/むンポヌト時間の考慮事項ず冗長性に基づいおいたす。 非垞に簡単に蚀えば、眲名が同じたたである可​​胜性が高いディスパッチャをマヌゞしたす。 このようにしお、䜜成するオブゞェクトの量を最小限に抑え、キャッシュヒットも高くなりたす。

そうは蚀っおも、私はラムダスタむルにあたり反察しおいたせん。

ディスパッチャ関数を䜜成するためのスタむルが、いく぀かのPRで登堎したした。 NumPy党䜓で䞀貫した遞択をするのは良いこずです。

いく぀かのオプションがありたす。


オプション1 関数ごずに個別のディスパッチャヌを䜜成したす。䟋

def _sin_dispatcher(a):
    return (a,)


@array_function_dispatch(_sin_dispatcher)
def sin(a):
     ...


def _cos_dispatcher(a):
    return (a,)


@array_function_dispatch(_cos_dispatcher)
def cos(a):
    ...

利点

  • 非垞に読みやすい
  • ディスパッチャ関数の定矩を簡単に芋぀ける
  • sin(x=1) -> TypeError: _sin_dispatcher() got an unexpected keyword argument 'x' 、間違った匕数を指定するず゚ラヌメッセヌゞがクリアされたす。

短所

  • モゞュヌル内の倚くの関数がたったく同じシグニチャを持っおいる堎合でも、倚くの繰り返し。

オプション2 モゞュヌル内のディスパッチャ関数を再利甚したす。

def _unary_dispatcher(a):
    return (a,)


@array_function_dispatch(_unary_dispatcher)
def sin(a):
     ...


@array_function_dispatch(_unary_dispatcher)
def cos(a):
    ...

利点

  • 繰り返しが少ない
  • 読みやすい

短所

  • ディスパッチャ関数の定矩を芋぀けるのが少し難しい堎合がありたす
  • sin(x=1) -> TypeError: _unary_dispatcher() got an unexpected keyword argument 'x'など、䞍正な匕数に察する゚ラヌメッセヌゞが少しわかりにくくなりたす

オプション3 ディスパッチャ定矩が1行に収たる堎合は、 lambda関数を䜿甚したす。

# inline style (shorter)
@array_function_dispatch(lambda a: (a,))
def sin(a):
     ...


@array_function_dispatch(lambda a, n=None, axis=None, norm=None: (a,))
def fft(a, n=None, axis=-1, norm=None):
     ...
# multiline style (more readable?)
@array_function_dispatch(
    lambda a: (a,)
)
def sin(a):
     ...


@array_function_dispatch(
    lambda a, n=None, axis=None, norm=None: (a,)
)
def fft(a, n=None, axis=-1, norm=None):
     ...

利点

  • ディスパッチャの定矩を探す必芁はありたせん。ディスパッチャの定矩はすぐそこにありたす。
  • 文字数ずコヌド行数が少なくなりたす。
  • 短い堎合たずえば、1぀の匕数、特にラムダが関数名よりも短い堎合に非垞に芋栄えがしたす。

短所

  • オプション2よりも繰り返されるコヌド。
  • 匕数が少なすぎるずかなり雑然ず芋えたす
  • たた、明確でない゚ラヌメッセヌゞがありたす TypeError: <lambda>() got an unexpected keyword argument 'x' 

@shoyer 「コヌド行」の偎面をより珟実的にするために2行のPEP8間隔を远加するように線集されたした

゚ラヌメッセヌゞの問題は、コヌドオブゞェクトを再構築するこずで修正できるこずに泚意しおください。ただし、むンポヌトには倚少のコストがかかりたす。 おそらく調査し、 @ nschloeのマグロを分解しおいく぀かのオプションを比范する䟡倀がありたす。

はい、デコレヌタモゞュヌルは関数定矩の生成にも䜿甚できたすコヌド生成には少し異なるアプロヌチを䜿甚したす。 exec()䜿甚するずいう点でnamedtupleに少し䌌おいたす。

゚ラヌが解決されない限り、明確な名前を持぀ディスパッチャでオプションに固執する必芁があるず思いたす。 メモリ䞊の理由からディスパッチャを少しバンドルしたす2が、゚ラヌメッセヌゞを非垞に念頭に眮いおいるので、ディスパッチャを_dispatch_on_xように呌び出すこずをお勧めしたす。

゚ラヌを倉曎できれば、状況は倉わりたす。 たずえば、䟋倖をキャッチし、 <lambda>を䟋倖テキストの関数名に眮き換えおから、再床発生させるのず同じくらい簡単な堎合がありたす。 たたは、そのチェヌンは最近のものですか

゚ラヌメッセヌゞは明確である必芁があり、理想的にはたったく倉曎されるべきではないこずに同意したす。

さお、今のずころ、䜕らかのコヌド生成が機胜しない限り、 lambda䜿甚を控えるのが最善だず思いたす。

https://github.com/numpy/numpy/pull/12175は、Pythonラッパヌアプロヌチを採甚した堎合にマルチアレむ関数Cで蚘述のオヌバヌラむドがどのように芋えるかに぀いおのドラフトを远加しおいたす。

@mattip matmulをufuncずしお実装するのはどこですか これらすべおの__array_function__オヌバヌラむドを完了したら、それがNumPyのパブリックAPIを完党にオヌバヌロヌド可胜にするために必芁な最埌のこずだず思いたす。 NumPy1.16の準備がすべお敎っおいるず䟿利です。

NEP 20を実装するPR11175は、ゆっくりず進んでいたす。 これは、matmulルヌプコヌドを持぀PR11133のブロッカヌです。 それでも曎新しお、ベンチマヌクを介しお新しいコヌドが叀いコヌドより遅くないこずを確認する必芁がありたす。

オヌバヌラむドの完党なセットを完了する必芁があるレビュヌ甚の4぀のPRがありたす。 __array_function__テストを本栌的に開始できるように、最終レビュヌ/サむンオフ/マヌゞをいただければ幞いです。 https://github.com/numpy/numpy/pull/12154 、 https://github.com/numpy/numpy/pull/12163 、 https://github.com/numpy/numpy/pull/12119 、 HTTPS //github.com/numpy/numpy/pull/12175

np.coreオヌバヌラむドを远加するず、いく぀かのパンダテストが倱敗したしたhttps://github.com/pandas-dev/pandas/issues/23172。 䜕が起こっおいるのかはただよくわかりたせんが、リリヌスする前に確実に把握する必芁がありたす。

これがdask / pandasでテストの倱敗を匕き起こしおいる理由に぀いおの私の最善の掚枬に぀いおは、 https//github.com/numpy/numpy/issues/12225を参照しお

むンポヌト時間のいく぀かのベンチマヌク゜リッドステヌトドラむブを搭茉した私のmacbook proで

  • NumPy 1.15.2152.451ミリ秒
  • NumPyマスタヌ156.5745ミリ秒
  • decorator.decorate 12226の䜿甚183.694ミリ秒

私のベンチマヌクスクリプト

import numpy as np
import subprocess

times = []
for _ in range(100):
    result = subprocess.run("python -X importtime -c 'import numpy'",
                            shell=True, capture_output=True)
    last_line = result.stderr.rstrip().split(b'\n')[-1]
    time = float(last_line.decode('ascii')[-15:-7].strip().rstrip())
    times.append(time)

print(np.median(times) / 1e3)

メモリ䜿甚量前/埌に぀いお䜕か考えはありたすか これは、特にIoTアプリケヌションにずっおも䟿利です。

モゞュヌルのメモリ䜿甚量を確実に枬定する方法を知っおいたすか
6:56 Hameerアッバヌスィヌの土曜、2018幎10月20日には[email protected]
曞きたした

メモリ䜿甚量前/埌に぀いお䜕か考えはありたすか それは䞀皮の䟿利です
特にIoTアプリケヌションの堎合はそうです。

—
あなたが蚀及されたのであなたはこれを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/numpy/numpy/issues/12028#issuecomment-431584123 、たたはミュヌト
スレッド
https://github.com/notifications/unsubscribe-auth/ABKS1k_IkrJ2YmYReaDrnkNvcH2X0-ZCks5umyuogaJpZM4W3kSC
。

import numpy as npを含むスクリプトを䜜成し、スリヌプステヌトメントを远加し、プロセスメモリを远跡するだけで十分だず思いたす。 https://superuser.com/questions/581108/how-can-i-track-and-log-cpu-and-memory-usage-on-a-mac

他のコア開発者は、 https//github.com/numpy/numpy/pull/12163で簡単に調べたいず思っおいたす実際には、2぀の関数しか含たれおいたせん array_function_dispatchを远加する最埌のPRです。

参考たでに、 __array_function__無効にしたずきに衚瀺されるパフォヌマンスの違いは次のずおりです。

       before           after         ratio
     [45718fd7]       [4e5aa2cd]
     <master>         <disable-array-function>
+        72.5±2ms         132±20ms     1.82  bench_io.LoadtxtCSVdtypes.time_loadtxt_dtypes_csv('complex128', 10000)
-        44.9±2Όs       40.8±0.6Όs     0.91  bench_ma.Concatenate.time_it('ndarray', 2)
-      15.3±0.3Όs       13.3±0.7Όs     0.87  bench_core.CountNonzero.time_count_nonzero_multi_axis(2, 100, <type 'object'>)
-        38.4±1Όs         32.7±2Όs     0.85  bench_linalg.Linalg.time_op('norm', 'longfloat')
-        68.7±3Όs         56.5±3Όs     0.82  bench_linalg.Linalg.time_op('norm', 'complex256')
-        80.6±4Όs         65.9±1Όs     0.82  bench_function_base.Median.time_even
-        82.4±2Όs         66.8±3Όs     0.81  bench_shape_base.Block.time_no_lists(100)
-        73.5±3Όs         59.3±3Όs     0.81  bench_function_base.Median.time_even_inplace
-      15.2±0.3Όs       12.2±0.6Όs     0.80  bench_core.CountNonzero.time_count_nonzero_multi_axis(3, 100, <type 'str'>)
-      2.20±0.1ms      1.76±0.04ms     0.80  bench_shape_base.Block2D.time_block2d((1024, 1024), 'uint64', (4, 4))
-        388±20Όs         310±10Όs     0.80  bench_lib.Pad.time_pad((10, 10, 10), 3, 'linear_ramp')
-        659±20Όs         524±20Όs     0.80  bench_linalg.Linalg.time_op('det', 'float32')
-      22.9±0.7Όs       18.2±0.8Όs     0.79  bench_function_base.Where.time_1
-        980±50Όs         775±20Όs     0.79  bench_shape_base.Block2D.time_block2d((1024, 1024), 'uint32', (4, 4))
-        36.6±1Όs         29.0±1Όs     0.79  bench_ma.Concatenate.time_it('unmasked', 2)
-      16.4±0.7Όs       12.9±0.6Όs     0.79  bench_core.CountNonzero.time_count_nonzero_axis(3, 100, <type 'str'>)
-      16.4±0.5Όs       12.9±0.4Όs     0.79  bench_core.CountNonzero.time_count_nonzero_axis(2, 100, <type 'object'>)
-         141±5Όs          110±4Όs     0.78  bench_lib.Pad.time_pad((10, 100), (0, 5), 'linear_ramp')
-      18.0±0.6Όs       14.1±0.6Όs     0.78  bench_core.CountNonzero.time_count_nonzero_axis(3, 100, <type 'object'>)
-      11.9±0.6Όs       9.28±0.5Όs     0.78  bench_core.CountNonzero.time_count_nonzero_axis(1, 100, <type 'int'>)
-        54.6±3Όs         42.4±2Όs     0.78  bench_function_base.Median.time_odd_small
-        317±10Όs          246±7Όs     0.78  bench_lib.Pad.time_pad((10, 10, 10), 1, 'linear_ramp')
-      13.8±0.5Όs       10.7±0.7Όs     0.77  bench_reduce.MinMax.time_min(<type 'numpy.float64'>)
-        73.3±6Όs         56.6±4Όs     0.77  bench_lib.Pad.time_pad((1000,), (0, 5), 'mean')
-      14.7±0.7Όs       11.4±0.3Όs     0.77  bench_core.CountNonzero.time_count_nonzero_axis(2, 100, <type 'str'>)
-        21.5±2Όs       16.5±0.6Όs     0.77  bench_reduce.MinMax.time_min(<type 'numpy.int64'>)
-         117±4Όs         89.2±3Όs     0.76  bench_lib.Pad.time_pad((1000,), 3, 'linear_ramp')
-        43.7±1Όs         33.4±1Όs     0.76  bench_linalg.Linalg.time_op('norm', 'complex128')
-      12.6±0.6Όs       9.55±0.2Όs     0.76  bench_core.CountNonzero.time_count_nonzero_multi_axis(2, 100, <type 'int'>)
-        636±20Όs         482±20Όs     0.76  bench_ma.MA.time_masked_array_l100
-        86.6±4Όs         65.6±4Όs     0.76  bench_lib.Pad.time_pad((1000,), (0, 5), 'linear_ramp')
-         120±4Όs         90.4±2Όs     0.75  bench_lib.Pad.time_pad((1000,), 1, 'linear_ramp')
-         160±5Όs          119±8Όs     0.74  bench_ma.Concatenate.time_it('ndarray+masked', 100)
-      14.4±0.6Όs       10.7±0.3Όs     0.74  bench_core.CountNonzero.time_count_nonzero_multi_axis(1, 100, <type 'str'>)
-      15.7±0.4Όs       11.7±0.6Όs     0.74  bench_core.CountNonzero.time_count_nonzero_multi_axis(2, 100, <type 'str'>)
-        21.8±2Όs       16.1±0.7Όs     0.74  bench_reduce.MinMax.time_max(<type 'numpy.int64'>)
-      11.9±0.6Όs       8.79±0.3Όs     0.74  bench_core.CountNonzero.time_count_nonzero_axis(2, 100, <type 'bool'>)
-        53.8±3Όs         39.4±2Όs     0.73  bench_function_base.Median.time_even_small
-        106±20Όs         76.7±4Όs     0.73  bench_function_base.Select.time_select
-        168±10Όs          122±4Όs     0.72  bench_shape_base.Block2D.time_block2d((512, 512), 'uint32', (2, 2))
-      12.5±0.5Όs       8.96±0.4Όs     0.72  bench_core.CountNonzero.time_count_nonzero_multi_axis(1, 100, <type 'int'>)
-        162±10Όs          115±5Όs     0.71  bench_function_base.Percentile.time_percentile
-        12.9±1Όs       9.12±0.4Όs     0.71  bench_random.Random.time_rng('normal')
-      9.71±0.4Όs       6.88±0.3Όs     0.71  bench_core.CorrConv.time_convolve(1000, 10, 'full')
-      15.1±0.8Όs       10.7±0.4Όs     0.71  bench_reduce.MinMax.time_max(<type 'numpy.float64'>)
-         153±9Όs          108±7Όs     0.71  bench_shape_base.Block2D.time_block2d((1024, 1024), 'uint8', (2, 2))
-         109±5Όs         76.9±5Όs     0.71  bench_ma.Concatenate.time_it('ndarray+masked', 2)
-        34.3±1Όs       24.2±0.6Όs     0.71  bench_linalg.Linalg.time_op('norm', 'complex64')
-      9.80±0.2Όs       6.84±0.5Όs     0.70  bench_core.CorrConv.time_convolve(1000, 10, 'same')
-        27.4±6Όs         19.1±2Όs     0.70  bench_core.CountNonzero.time_count_nonzero_axis(1, 10000, <type 'bool'>)
-      9.35±0.4Όs       6.50±0.3Όs     0.70  bench_core.CorrConv.time_convolve(50, 100, 'full')
-        65.2±4Όs         45.2±1Όs     0.69  bench_shape_base.Block.time_block_simple_row_wise(100)
-        12.9±1Όs       8.89±0.3Όs     0.69  bench_core.CountNonzero.time_count_nonzero_axis(3, 100, <type 'bool'>)
-        19.6±3Όs       13.5±0.4Όs     0.69  bench_core.CountNonzero.time_count_nonzero_multi_axis(3, 100, <type 'object'>)
-        75.6±2Όs         52.1±3Όs     0.69  bench_lib.Pad.time_pad((10, 10, 10), (0, 5), 'reflect')
-        12.4±1Όs       8.51±0.4Όs     0.69  bench_core.CountNonzero.time_count_nonzero_multi_axis(3, 100, <type 'bool'>)
-        172±30Όs          117±4Όs     0.68  bench_ma.Concatenate.time_it('unmasked+masked', 100)
-      23.1±0.5Όs       15.8±0.9Όs     0.68  bench_linalg.Linalg.time_op('norm', 'int16')
-      8.18±0.9Όs       5.57±0.1Όs     0.68  bench_core.CorrConv.time_correlate(1000, 10, 'full')
-         153±5Όs          103±3Όs     0.68  bench_function_base.Percentile.time_quartile
-       758±100Όs         512±20Όs     0.68  bench_linalg.Linalg.time_op('det', 'int16')
-        55.4±6Όs         37.4±1Όs     0.68  bench_ma.Concatenate.time_it('masked', 2)
-        234±30Όs          157±5Όs     0.67  bench_shape_base.Block.time_nested(100)
-         103±4Όs         69.3±3Όs     0.67  bench_linalg.Eindot.time_dot_d_dot_b_c
-      19.2±0.4Όs       12.9±0.6Όs     0.67  bench_core.Core.time_tril_l10x10
-         122±7Όs         81.7±4Όs     0.67  bench_lib.Pad.time_pad((10, 10, 10), 3, 'edge')
-        22.9±1Όs       15.3±0.5Όs     0.67  bench_linalg.Linalg.time_op('norm', 'int32')
-        16.6±2Όs       11.0±0.3Όs     0.66  bench_core.CountNonzero.time_count_nonzero_multi_axis(1, 100, <type 'object'>)
-      9.98±0.3Όs       6.58±0.1Όs     0.66  bench_core.CorrConv.time_convolve(1000, 10, 'valid')
-         118±6Όs         77.9±4Όs     0.66  bench_shape_base.Block2D.time_block2d((512, 512), 'uint16', (2, 2))
-        212±50Όs          140±8Όs     0.66  bench_lib.Pad.time_pad((10, 10, 10), (0, 5), 'mean')
-      21.9±0.7Όs       14.4±0.5Όs     0.66  bench_linalg.Linalg.time_op('norm', 'int64')
-         131±5Όs         85.9±5Όs     0.65  bench_lib.Pad.time_pad((10, 10, 10), 3, 'constant')
-        56.8±2Όs         37.0±3Όs     0.65  bench_lib.Pad.time_pad((1000,), (0, 5), 'constant')
-        58.9±3Όs         38.1±1Όs     0.65  bench_lib.Pad.time_pad((10, 100), (0, 5), 'reflect')
-        72.1±2Όs         46.5±3Όs     0.64  bench_lib.Pad.time_pad((10, 100), (0, 5), 'constant')
-      8.66±0.3Όs       5.58±0.2Όs     0.64  bench_core.CorrConv.time_correlate(50, 100, 'full')
-        300±30Όs         193±10Όs     0.64  bench_shape_base.Block2D.time_block2d((1024, 1024), 'uint8', (4, 4))
-        15.9±5Όs       10.2±0.3Όs     0.64  bench_core.CountNonzero.time_count_nonzero_axis(3, 100, <type 'int'>)
-      13.7±0.5Όs       8.80±0.1Όs     0.64  bench_random.Random.time_rng('uniform')
-      8.60±0.5Όs       5.50±0.2Όs     0.64  bench_core.CorrConv.time_correlate(1000, 10, 'same')
-        44.7±2Όs       28.5±0.7Όs     0.64  bench_lib.Pad.time_pad((1000,), 1, 'reflect')
-        72.7±3Όs         46.2±2Όs     0.64  bench_lib.Pad.time_pad((10, 10, 10), 3, 'wrap')
-        567±50Όs         360±40Όs     0.63  bench_shape_base.Block2D.time_block2d((512, 512), 'uint64', (2, 2))
-        58.0±3Όs         36.7±2Όs     0.63  bench_lib.Pad.time_pad((10, 100), 3, 'reflect')
-        219±30Όs          138±7Όs     0.63  bench_lib.Pad.time_pad((10, 100), 1, 'mean')
-        261±60Όs         164±10Όs     0.63  bench_lib.Pad.time_pad((10, 100), 1, 'linear_ramp')
-       825±100Όs         519±30Όs     0.63  bench_shape_base.Block2D.time_block2d((512, 512), 'uint64', (4, 4))
-         121±5Όs         75.7±2Όs     0.63  bench_lib.Pad.time_pad((10, 10, 10), 1, 'constant')
-      8.16±0.2Όs       5.08±0.4Όs     0.62  bench_core.CorrConv.time_convolve(50, 100, 'same')
-        66.6±3Όs         41.3±2Όs     0.62  bench_lib.Pad.time_pad((1000,), 3, 'constant')
-        53.1±3Όs       32.9±0.8Όs     0.62  bench_lib.Pad.time_pad((10, 100), 3, 'wrap')
-        285±60Όs         177±10Όs     0.62  bench_lib.Pad.time_pad((10, 10, 10), (0, 5), 'linear_ramp')
-      8.30±0.9Όs       5.14±0.1Όs     0.62  bench_core.CorrConv.time_correlate(1000, 10, 'valid')
-         115±3Όs         71.2±3Όs     0.62  bench_shape_base.Block2D.time_block2d((256, 256), 'uint64', (2, 2))
-      19.1±0.5Όs       11.8±0.6Όs     0.62  bench_linalg.Linalg.time_op('norm', 'float64')
-        95.3±5Όs         58.6±2Όs     0.62  bench_lib.Pad.time_pad((10, 100), 1, 'constant')
-        44.6±1Όs       27.2±0.9Όs     0.61  bench_lib.Pad.time_pad((1000,), (0, 5), 'edge')
-        447±20Όs         270±10Όs     0.61  bench_shape_base.Block2D.time_block2d((1024, 1024), 'uint16', (4, 4))
-        53.9±2Όs         32.6±2Όs     0.60  bench_lib.Pad.time_pad((10, 100), 1, 'wrap')
-        11.6±1Όs       6.97±0.4Όs     0.60  bench_reduce.MinMax.time_max(<type 'numpy.float32'>)
-        95.9±5Όs         57.7±2Όs     0.60  bench_lib.Pad.time_pad((10, 100), 3, 'constant')
-        47.2±2Όs         28.2±2Όs     0.60  bench_lib.Pad.time_pad((1000,), (0, 5), 'reflect')
-      5.51±0.2Όs      3.27±0.07Όs     0.59  bench_core.CountNonzero.time_count_nonzero(3, 100, <type 'object'>)
-        74.3±3Όs         44.0±2Όs     0.59  bench_lib.Pad.time_pad((10, 10, 10), (0, 5), 'wrap')
-        76.2±3Όs       45.0±0.8Όs     0.59  bench_lib.Pad.time_pad((10, 10, 10), 1, 'reflect')
-        57.1±1Όs         33.5±2Όs     0.59  bench_lib.Pad.time_pad((10, 100), (0, 5), 'wrap')
-        52.0±2Όs         30.4±1Όs     0.58  bench_lib.Pad.time_pad((1000,), 1, 'edge')
-        42.6±2Όs       24.9±0.9Όs     0.58  bench_lib.Pad.time_pad((1000,), 3, 'wrap')
-        15.0±3Όs       8.73±0.3Όs     0.58  bench_core.CountNonzero.time_count_nonzero_multi_axis(1, 100, <type 'bool'>)
-        16.0±3Όs       9.29±0.3Όs     0.58  bench_core.CountNonzero.time_count_nonzero_multi_axis(3, 100, <type 'int'>)
-        53.1±1Όs         30.9±2Όs     0.58  bench_lib.Pad.time_pad((1000,), 3, 'edge')
-        88.0±8Όs         51.1±3Όs     0.58  bench_lib.Pad.time_pad((10, 10, 10), 3, 'reflect')
-        44.6±2Όs         25.9±1Όs     0.58  bench_lib.Pad.time_pad((1000,), (0, 5), 'wrap')
-        90.3±5Όs         51.9±1Όs     0.57  bench_shape_base.Block2D.time_block2d((512, 512), 'uint8', (2, 2))
-      15.6±0.5Όs       8.93±0.3Όs     0.57  bench_linalg.Linalg.time_op('norm', 'float32')
-         102±6Όs       58.3±0.9Όs     0.57  bench_lib.Pad.time_pad((10, 10, 10), 1, 'edge')
-        80.1±4Όs         45.6±3Όs     0.57  bench_lib.Pad.time_pad((10, 100), 3, 'edge')
-        44.2±2Όs         24.9±1Όs     0.56  bench_lib.Pad.time_pad((1000,), 1, 'wrap')
-        71.6±8Όs         39.5±1Όs     0.55  bench_lib.Pad.time_pad((10, 10, 10), 1, 'wrap')
-       81.7±10Όs         44.8±2Όs     0.55  bench_lib.Pad.time_pad((10, 100), 1, 'edge')
-        420±90Όs         230±10Όs     0.55  bench_shape_base.Block.time_3d(10, 'block')
-        114±20Όs         62.3±2Όs     0.55  bench_lib.Pad.time_pad((10, 10, 10), (0, 5), 'constant')
-      5.76±0.1Όs      3.13±0.08Όs     0.54  bench_core.CorrConv.time_convolve(50, 10, 'same')
-      5.30±0.1Όs      2.84±0.08Όs     0.54  bench_core.CorrConv.time_correlate(50, 100, 'valid')
-        92.5±4Όs         49.3±1Όs     0.53  bench_shape_base.Block2D.time_block2d((256, 256), 'uint32', (2, 2))
-        13.5±3Όs       7.07±0.2Όs     0.52  bench_reduce.MinMax.time_min(<type 'numpy.float32'>)
-        7.66±1Όs       3.88±0.2Όs     0.51  bench_core.CorrConv.time_convolve(50, 100, 'valid')
-        29.0±3Όs       14.5±0.8Όs     0.50  bench_shape_base.Block.time_no_lists(10)
-      6.62±0.3Όs       3.30±0.2Όs     0.50  bench_core.CorrConv.time_convolve(1000, 1000, 'valid')
-        74.2±7Όs       36.2±0.9Όs     0.49  bench_shape_base.Block2D.time_block2d((256, 256), 'uint16', (2, 2))
-      5.55±0.3Όs       2.70±0.2Όs     0.49  bench_core.CorrConv.time_convolve(50, 10, 'valid')
-       73.9±20Όs         35.8±2Όs     0.48  bench_lib.Pad.time_pad((10, 100), 1, 'reflect')
-        224±20Όs          107±7Όs     0.48  bench_shape_base.Block2D.time_block2d((256, 256), 'uint64', (4, 4))
-      3.87±0.1Όs      1.83±0.06Όs     0.47  bench_core.CountNonzero.time_count_nonzero(2, 100, <type 'str'>)
-        109±30Όs         51.5±3Όs     0.47  bench_lib.Pad.time_pad((10, 10, 10), (0, 5), 'edge')
-        240±20Όs          112±4Όs     0.47  bench_shape_base.Block2D.time_block2d((512, 512), 'uint16', (4, 4))
-        337±40Όs          158±7Όs     0.47  bench_shape_base.Block2D.time_block2d((512, 512), 'uint32', (4, 4))
-         188±8Όs         88.0±2Όs     0.47  bench_shape_base.Block2D.time_block2d((512, 512), 'uint8', (4, 4))
-      4.39±0.2Όs      2.04±0.09Όs     0.47  bench_core.CountNonzero.time_count_nonzero(3, 10000, <type 'bool'>)
-        73.2±4Όs       33.9±0.5Όs     0.46  bench_shape_base.Block2D.time_block2d((128, 128), 'uint64', (2, 2))
-        5.48±1Όs       2.44±0.1Όs     0.45  bench_core.CountNonzero.time_count_nonzero(2, 100, <type 'object'>)
-      4.46±0.1Όs      1.97±0.08Όs     0.44  bench_core.CorrConv.time_correlate(50, 10, 'full')
-        30.4±9Όs       13.3±0.3Όs     0.44  bench_shape_base.Block.time_no_lists(1)
-      7.05±0.2Όs      3.05±0.06Όs     0.43  bench_reduce.SmallReduction.time_small
-        7.35±1Όs       3.12±0.2Όs     0.42  bench_core.CorrConv.time_convolve(50, 10, 'full')
-      4.36±0.1Όs      1.84±0.07Όs     0.42  bench_core.CorrConv.time_correlate(50, 10, 'same')
-      3.51±0.2Όs      1.46±0.05Όs     0.42  bench_core.CountNonzero.time_count_nonzero(1, 100, <type 'object'>)
-     4.03±0.05Όs       1.66±0.1Όs     0.41  bench_core.CorrConv.time_correlate(1000, 1000, 'valid')
-        199±10Όs         80.1±3Όs     0.40  bench_shape_base.Block2D.time_block2d((256, 256), 'uint32', (4, 4))
-      3.98±0.2Όs      1.60±0.08Όs     0.40  bench_core.CountNonzero.time_count_nonzero(2, 10000, <type 'bool'>)
-        61.8±2Όs         24.8±1Όs     0.40  bench_shape_base.Block2D.time_block2d((256, 256), 'uint8', (2, 2))
-      4.13±0.1Όs      1.62±0.05Όs     0.39  bench_core.CorrConv.time_correlate(50, 10, 'valid')
-        61.6±2Όs         23.9±1Όs     0.39  bench_shape_base.Block2D.time_block2d((128, 128), 'uint32', (2, 2))
-        184±10Όs         70.5±3Όs     0.38  bench_shape_base.Block2D.time_block2d((256, 256), 'uint16', (4, 4))
-        56.1±4Όs       21.0±0.9Όs     0.38  bench_shape_base.Block2D.time_block2d((64, 64), 'uint64', (2, 2))
-        40.0±2Όs       15.0±0.6Όs     0.37  bench_shape_base.Block.time_block_simple_column_wise(10)
-         121±2Όs         45.1±2Όs     0.37  bench_shape_base.Block.time_nested(1)
-         179±4Όs         66.1±4Όs     0.37  bench_shape_base.Block2D.time_block2d((128, 128), 'uint64', (4, 4))
-        59.8±2Όs         22.0±1Όs     0.37  bench_shape_base.Block2D.time_block2d((128, 128), 'uint16', (2, 2))
-     3.19±0.05Όs      1.17±0.02Όs     0.37  bench_core.CountNonzero.time_count_nonzero(1, 100, <type 'str'>)
-        54.0±3Όs         19.7±1Όs     0.37  bench_shape_base.Block2D.time_block2d((32, 32), 'uint64', (2, 2))
-        56.9±1Όs       20.7±0.7Όs     0.36  bench_shape_base.Block2D.time_block2d((64, 64), 'uint32', (2, 2))
-      3.14±0.1Όs      1.14±0.04Όs     0.36  bench_core.CountNonzero.time_count_nonzero(1, 10000, <type 'bool'>)
-        92.7±2Όs         33.7±2Όs     0.36  bench_shape_base.Block.time_block_complicated(1)
-         104±4Όs         37.8±1Όs     0.36  bench_shape_base.Block.time_block_complicated(10)
-         128±5Όs         45.5±2Όs     0.36  bench_shape_base.Block.time_nested(10)
-       196±100Όs         69.4±3Όs     0.35  bench_ma.Concatenate.time_it('unmasked+masked', 2)
-         153±5Όs         53.9±2Όs     0.35  bench_shape_base.Block2D.time_block2d((128, 128), 'uint16', (4, 4))
-        39.4±2Όs       13.8±0.5Όs     0.35  bench_shape_base.Block.time_block_simple_column_wise(1)
-        53.5±2Όs         18.7±1Όs     0.35  bench_shape_base.Block2D.time_block2d((32, 32), 'uint8', (2, 2))
-        55.2±2Όs       19.3±0.6Όs     0.35  bench_shape_base.Block2D.time_block2d((32, 32), 'uint16', (2, 2))
-        16.9±1Όs       5.89±0.5Όs     0.35  bench_core.Core.time_dstack_l
-        60.6±3Όs       21.1±0.6Όs     0.35  bench_shape_base.Block2D.time_block2d((128, 128), 'uint8', (2, 2))
-      25.5±0.2Όs       8.88±0.3Όs     0.35  bench_shape_base.Block.time_block_simple_row_wise(10)
-        54.6±3Όs       19.0±0.6Όs     0.35  bench_shape_base.Block2D.time_block2d((16, 16), 'uint64', (2, 2))
-        52.6±2Όs       18.2±0.7Όs     0.35  bench_shape_base.Block2D.time_block2d((16, 16), 'uint16', (2, 2))
-        6.57±2Όs      2.25±0.08Όs     0.34  bench_core.CountNonzero.time_count_nonzero(3, 100, <type 'str'>)
-        24.3±1Όs       8.30±0.6Όs     0.34  bench_shape_base.Block.time_block_simple_row_wise(1)
-         148±3Όs         50.0±3Όs     0.34  bench_shape_base.Block2D.time_block2d((16, 16), 'uint32', (4, 4))
-         171±8Όs         57.9±4Όs     0.34  bench_shape_base.Block2D.time_block2d((256, 256), 'uint8', (4, 4))
-         159±5Όs         53.8±1Όs     0.34  bench_shape_base.Block2D.time_block2d((64, 64), 'uint64', (4, 4))
-        171±20Όs         57.7±2Όs     0.34  bench_shape_base.Block2D.time_block2d((128, 128), 'uint32', (4, 4))
-      3.15±0.3Όs      1.06±0.03Όs     0.34  bench_core.CountNonzero.time_count_nonzero(3, 100, <type 'int'>)
-        55.7±5Όs       18.7±0.2Όs     0.34  bench_shape_base.Block2D.time_block2d((16, 16), 'uint8', (2, 2))
-         158±7Όs         52.6±3Όs     0.33  bench_shape_base.Block2D.time_block2d((128, 128), 'uint8', (4, 4))
-         153±4Όs         50.7±1Όs     0.33  bench_shape_base.Block2D.time_block2d((32, 32), 'uint64', (4, 4))
-         152±7Όs         50.3±1Όs     0.33  bench_shape_base.Block2D.time_block2d((16, 16), 'uint8', (4, 4))
-        53.6±3Όs       17.7±0.4Όs     0.33  bench_shape_base.Block2D.time_block2d((16, 16), 'uint32', (2, 2))
-         156±4Όs         51.4±3Όs     0.33  bench_shape_base.Block2D.time_block2d((64, 64), 'uint8', (4, 4))
-         148±3Όs         48.2±2Όs     0.33  bench_shape_base.Block2D.time_block2d((16, 16), 'uint16', (4, 4))
-        160±10Όs         52.0±1Όs     0.33  bench_shape_base.Block2D.time_block2d((64, 64), 'uint32', (4, 4))
-         159±8Όs         51.4±3Όs     0.32  bench_shape_base.Block2D.time_block2d((64, 64), 'uint16', (4, 4))
-        59.8±3Όs         19.3±1Όs     0.32  bench_shape_base.Block2D.time_block2d((32, 32), 'uint32', (2, 2))
-         153±4Όs         49.4±2Όs     0.32  bench_shape_base.Block2D.time_block2d((32, 32), 'uint32', (4, 4))
-      15.6±0.6Όs       5.03±0.3Όs     0.32  bench_core.Core.time_vstack_l
-         154±7Όs         49.7±2Όs     0.32  bench_shape_base.Block2D.time_block2d((32, 32), 'uint8', (4, 4))
-        59.6±6Όs       19.1±0.8Όs     0.32  bench_shape_base.Block2D.time_block2d((64, 64), 'uint8', (2, 2))
-      3.03±0.4Όs         969±30ns     0.32  bench_core.CountNonzero.time_count_nonzero(2, 100, <type 'int'>)
-        120±10Όs         38.4±2Όs     0.32  bench_shape_base.Block.time_3d(1, 'block')
-         156±5Όs         49.3±1Όs     0.32  bench_shape_base.Block2D.time_block2d((16, 16), 'uint64', (4, 4))
-        164±10Όs         49.3±2Όs     0.30  bench_shape_base.Block2D.time_block2d((32, 32), 'uint16', (4, 4))
-       65.7±10Όs       19.6±0.7Όs     0.30  bench_shape_base.Block2D.time_block2d((64, 64), 'uint16', (2, 2))
-     2.82±0.08Όs         732±30ns     0.26  bench_core.CountNonzero.time_count_nonzero(1, 100, <type 'int'>)
-     2.77±0.07Όs         664±30ns     0.24  bench_core.CountNonzero.time_count_nonzero(2, 100, <type 'bool'>)
-      2.61±0.1Όs         624±20ns     0.24  bench_core.CountNonzero.time_count_nonzero(1, 100, <type 'bool'>)
-        16.8±3Όs       3.97±0.2Όs     0.24  bench_core.Core.time_hstack_l
-      2.78±0.1Όs         637±20ns     0.23  bench_core.CountNonzero.time_count_nonzero(3, 100, <type 'bool'>)
-      2.36±0.2Όs          207±5ns     0.09  bench_overrides.ArrayFunction.time_mock_broadcast_to_numpy
-      2.68±0.1Όs          221±7ns     0.08  bench_overrides.ArrayFunction.time_mock_concatenate_numpy
-      2.58±0.1Όs         201±10ns     0.08  bench_overrides.ArrayFunction.time_mock_broadcast_to_duck
-      3.02±0.2Όs          222±6ns     0.07  bench_overrides.ArrayFunction.time_mock_concatenate_duck
-      4.29±0.3Όs          216±6ns     0.05  bench_overrides.ArrayFunction.time_mock_concatenate_mixed
-        142±20Όs          213±8ns     0.00  bench_overrides.ArrayFunction.time_mock_concatenate_many

SOME BENCHMARKS HAVE CHANGED SIGNIFICANTLY.

スプレッドシヌトに぀いおは、 https//docs.google.com/spreadsheets/d/15-AFI_cmZqfkU6mo2p1znsQF2E52PEXpF68QqYqEar4/edit#gid = 0も参照しお

圓然のこずながら、最倧のパフォヌマンスの違いは、他のnumpy関数を内郚で䜕床も呌び出す関数、たずえばnp.block()です。

@ shoyer-䜙分な時間がかかったこずに少し戞惑いたした...おそらく、実際にはCを実装する必芁がありたすが、その間に、1぀だけの䞀般的なケヌスで時間を削るいく぀かの小さな倉曎を加えおPRを行いたしたタむプ、およびタむプがndarrayのみの堎合。 12321を参照しおください。

@ shoyer-私はメヌリングリストで2぀の問題を提起したしたが、おそらくここでも述べおおくずよいでしょう。

  1. 配列のような匕数のすべおの䞀意のタむプをtypes含める必芁がありたすか オヌバヌラむドを提䟛する匕数だけでなく。実装に぀いお知っおおくず圹立぀ように思われたす。 12327を参照。
  2. __array_function__をオヌバヌラむドする堎合でも、 ndarray.__array_function__実装はサブクラスを受け入れる必芁がありたすか これは、リスコフの眮換原則ず、サブクラスがすでに保釈される機䌚があったこずを考えるず、合理的です。 これは、 ndarray.__array_function__内のパブリック関数ではなく、実装を呌び出すこずを意味したす。 そしお__array_ufunc__䌌たようなもの... __array_function__のみの詊甚版に぀いおは12328を参照しおください。

@ shoyer- 1の簡単な実装に぀いおは12327を参照しおください-このルヌトに行く堎合は、NEPも調敎する必芁があるず思いたす。

そしお、2のトラむアルのための12328、䞻にそれがどのように芋えるかを芋るために。

私はここで䞡方の倉曎で+1しおいたす。

゚ラヌメッセヌゞのディスパッチャ関数の名前がhttps://github.com/numpy/numpy/pull/12789に再び衚瀺され、誰かがTypeError: _pad_dispatcher missing 1 required positional argumentを芋お驚いた

䞊蚘で抂説した代替案https://github.com/numpy/numpy/issues/12028#issuecomment-429377396 珟圚2を䜿甚に加えお、4番目のオプションを远加したす。

オプション4 関数ず同じ名前で、関数ごずに個別のディスパッチャヌを蚘述したす。

def sin(a):
    return (a,)


@array_function_dispatch(sin)
def sin(a):
     ...


def cos(a):
    return (a,)


@array_function_dispatch(cos)
def cos(a):
    ...

利点

  • Pythonは、゚ラヌメッセヌゞで垞に正しい関数名を提䟛するようになりたした。

短所

  • より倚くのコヌドの繰り返し
  • より間接的な-どの関数名padが間違った匕数を受け取ったかはもはや明確ではありたせんただし、それらが同期されおいるこずを確認するためのテストがありたす。

珟圚のコヌドを機胜させ続けるためには、実際の関数はディスパッチャの_埌に_来る必芁があるず思いたす。

そうですが、ディスパッチャず同じ名前を付けるこずができたす。 コヌディネヌタヌ名は䞊曞きされたす。

np.arangeやnp.emptyなどの関数のカスタムディスパッチを定矩できるず䟿利です。

1぀のオプションは、NumPyが配列だけでなくスカラヌにもディスパッチするこずだず思いたす。 これはNEPず互換性がありたせんか この倉曎で䜕かが壊れたすか

np.arange説明に぀いおhttps//github.com/numpy/numpy/issues/12379を参照しお

np.empty()がどのようにディスパッチできるかわかりたせん。ディスパッチするものはなく、圢状ずdtypeだけです。 しかし、確かにnp.empty_like()は、䞊曞きされた圢状でディスパッチを実行できたす。これは、 https//github.com/numpy/numpy/pull/13046がサポヌトしおいるこずです。

オプション4 関数ず同じ名前で、関数ごずに個別のディスパッチャヌを蚘述したす。

このオプションを採甚するこずに異議はありたすか ナヌザヌの芳点からするず、おそらく最もフレンドリヌな遞択だず思いたす。

np.emptyがどのようにディスパッチを実行できるかわかりたせん-ディスパッチするものはなく、圢状ずdtypeだけです

あなたはそれらのどちらかに掟遣したいかもしれたせん。 たずえば、これはカスタムシェむプオブゞェクトであり、別の方法でディスパッチしたい堎合がありたす。

Screen Shot 2019-04-03 at 1 06 46 PM

この䟋はあたり圹に立ちたせんが、圢のように動䜜するが敎数を返さず、匏を返す怠惰なオブゞェクトがあるずいう考えです。 たずえば、次のようなこずができるず䟿利です。

class ExprShape:
    def __getitem__(self, i):
        return ('getitem', self, i)
    def __len__(self):
        return ('len', self)

numpy.empty(ExprShape())

ExprArray('empty', ExprShape())ようなものを返すために、どちらをオヌバヌラむドしたいず思いたすか。

はい、原則ずしお圢状で発送するこずも可胜です。 これにより、プロトコルがさらに耇雑/オヌバヌヘッドになりたす。 配列をテンプレヌトずしお䜿甚する empty_likeずshape だけでは䞍十分なナヌスケヌスはありたすか

私が考えるこずができる他のケヌスは、 size np.random.RandomStateメ゜ッドに察するsize匕数ですが、珟圚、それらをたったくサポヌトしおいないこずに泚意しおください-http//www.numpy.org/を参照しお

配列をテンプレヌトずしお䜿甚するshapeのempty_likeなどだけでは䞍十分なナヌスケヌスはありたすか

NumPyに䟝存する既存のAPIを䜿甚しおいお、既存の゜ヌスコヌドを倉曎せずに、別のバック゚ンドで透過的に機胜させたい堎合。

たずえば、配列のようなNPを䜿甚しおscipy.optimize.differential_evolutionを呌び出そうずしたずしたす。これにより、すぐに実行するのではなく、コヌルグラフが䜜成されたす。

あなたは芋るこずができ、ここで、我々は倉曎するこずができれば、それは参考になるnp.fullそれに枡された入力にも象城的だった堎合、代わりにデフォルトのnumpyの配列のシンボリックな配列を䜜成したす。

NumPyに䟝存する既存のAPIを䜿甚しおいお、既存の゜ヌスコヌドを倉曎せずに、別のバック゚ンドで透過的に機胜させたい堎合。

これは䞀般的には䞍可胜です。 np.array()ような明瀺的な配列構造は、ダックタむピングず互換性があるように間違いなく曞き盎す必芁がありたす。

この堎合、 energies = np.full(num_members, np.inf)をenergies = np.full_like(population, np.inf, shape=num_members)切り替えるのは、簡単で読みやすい倉曎のようです。

これは䞀般的には䞍可胜です。 np.arrayのような明瀺的な配列構造は、ダックタむピングず互換性があるように間違いなく曞き盎す必芁がありたす。

この皮の倉曎を行うこずに関する提案はありたすか、それずもnp.arrayディスパッチをサポヌトするこずは非垞に困難であり、100のサポヌトを埗るこずができないず蚀っおいたすか

この堎合、energies = np.fullnum_members、np.infをenergies = np.full_likepopulation、np.inf、shape = num_membersに切り替えるず、簡単で読みやすい倉曎のように芋えたす。

間違いなく。 しかし、゜ヌスコヌドを制埡しない堎合や、ナヌザヌが知っおいお気に入っおいる機胜を可胜な限り䜿甚できるようにサポヌトしたい堎合が倚くありたす。

ナヌザヌにその゚クスペリ゚ンスを提䟛する方法は他にもありたす。

  • numpyのように動䜜するが、垌望どおりに動䜜する新しいモゞュヌルを提䟛したす。 ナヌザヌはむンポヌトを倉曎する必芁がありたす
  • ゜ヌスを調べお、動䜜を理解したす。 alanumbaたたはタンゞェント。

特定の堎合ナヌザヌがnp.fullを呌び出しお、珟圚シンボリックな結果を返すようにするなどには、これらのオプションの䞡方が必芁になる堎合がありたすが、私が正しく理解しおいれば、NEP-18の目暙はそれらが必芁なずきに制限しようずするこずですより倚くの堎合、元のNumPyを䜿甚できるようにしたす。

ここにはパフォヌマンスず耇雑さのトレヌドオフがあるこずを理解しおいたす。これは、これらを実装しない理由になる可胜性がありたす。 しかし、それはナヌザヌに圌らが望む柔軟性を埗るために他の手段を探求するこずを匷いるかもしれたせん。

この皮の倉曎を行うこずに関する提案はありたすか、それずもnp.arrayディスパッチをサポヌトするこずは非垞に困難であり、100のサポヌトを埗るこずができないず蚀っおいたすか

NEP 22には、ここでのオプションに関するいく぀かの説明がありたす。 np.asarray()のセマンティクスを安党に倉曎しお、 numpy.ndarrayオブゞェクト以倖のものを返すこずはできないず思いたす。これには、新しいプロトコルが必芁になりたす。

問題は、 np.asarray()が珟圚、numpy配列オブゞェクトにキャストする慣甚的な方法であるずいうこずです。これは、たずえばメモリレむアりトに至るたで、 numpy.ndarrayず完党に䞀臎するこずができたす。

これが圓おはたらないナヌスケヌスは確かにたくさんありたすが、この動䜜を切り替えるず倚くのダりンストリヌムコヌドが砎損するため、初心者ではありたせん。 ダりンストリヌムプロゞェクトでは、少なくずも配列ダックタむピングのこの偎面にオプトむンする必芁がありたす。

ここにはパフォヌマンスず耇雑さのトレヌドオフがあるこずを理解しおいたす。これは、これらを実装しない理由になる可胜性がありたす。 しかし、それはナヌザヌに圌らが望む柔軟性を埗るために他の手段を探求するこずを匷いるかもしれたせん。

はい。 NEP 18は、ドロップむンNumPyの代替案の完党な゜リュヌションずなるこずを意図したものではありたせんが、その方向ぞの䞀歩です。

__numpy_implementation__属性を远加するためのNEP-18の改蚂版を䜜成したした。
https://github.com/numpy/numpy/pull/13305

numpy.testingの関数をワヌプするのを忘れおいるこずに気づきたした https 

私はすぐにそれをする぀もりです...

特にNEP-18がサブクラスの䜜成者に提䟛する保蚌を明確にするためにNEPに確認したい改蚂が1぀ありたす https 

gh-13329が修正されおから、ナヌザビリティタスクを完了ずしおマヌクしたした。 決定したした-13588は1.17のリリヌス埌たで埅぀こずができたす。 これにより、ドキュメントが改善され、 arange gh-12379は1.17に含めるこずができたす。

13728もありたす- histogram[2d]dディスパッチャのバグ

そのため、ドキュメントが改善され、gh-12379の範囲は1.17に含めるこずができたす。

ドキュメントの問題が欠萜しおいたので、gh-13844を開きたした。 ドキュメントはarange未解決の問題よりもはるかに重芁だず思いたす。

@shoyerこれを閉じるこずができたすか

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡