NumPy とMatplotlibライブラリを使用して作成された y=sin(x) 関数のプロット | |
| 原作者 | トラヴィス・オリファント |
|---|---|
| 開発者 | コミュニティプロジェクト |
| 初回リリース | Numeric として 1995 年、NumPy として 2006 年 |
| 安定版リリース | 2.2.1 [1]
/ 2024年12月21日 |
| リポジトリ |
|
| 書かれた | Python、C |
| オペレーティング·システム | クロスプラットフォーム |
| タイプ | 数値解析 |
| ライセンス | BSDS [2] |
| Webサイト | numpy.org |
NumPy(発音:/ ˈ n ʌ m p aɪ / NUM -py)は、Pythonプログラミング言語のライブラリであり、大規模な多次元配列と行列のサポートと、これらの配列を操作するための高度な数学関数の大規模なコレクションが追加されています。 [3] NumPyの前身であるNumericは、もともとJim Huguninが他の数人の開発者の貢献を得て作成しました。 2005年に、Travis Oliphantが競合するNumarrayの機能をNumericに組み込み、大幅な変更を加えてNumPyを作成しました。 NumPyはオープンソースソフトウェアであり、多くの貢献者がいます。 NumPyはNumFOCUSによって財政的に支援されています。[4]
歴史
マトリックス署名
Pythonプログラミング言語はもともと数値計算用に設計されたものではありませんでしたが、早い段階で科学および工学コミュニティの注目を集めました。1995年に配列計算パッケージを定義する目的で特別利益団体(SIG)matrix-sigが設立されました。そのメンバーの1人はPythonの設計者でありメンテナーでもあるGuido van Rossumで、彼はPythonの構文(特にインデックス構文[5] )を拡張して配列計算を容易にしました。[6]
数値
行列パッケージの実装はジム・フルトンによって完成され、その後ジム・ヒューガニンによって一般化され[さらなる説明が必要] 、 APLファミリーの言語、Basis、MATLAB、FORTRAN、S、S+などの影響を受けてNumeric [6](「Numerical Python extensions」または「NumPy」とも呼ばれる)と呼ばれました。 [7] [8]マサチューセッツ工科大学(MIT) の大学院生であったヒューガニンは[8] : 10 1997 年に国立研究イニシアチブ協会(CNRI)に加わり、[6]ローレンス・リバモア国立研究所(LLNL)のポール・デュボアがメンテナを引き継ぎました。[8] : 10 他の初期の貢献者には、デビッド・アッシャー、コンラッド・ヒンセン、トラビス・オリファントなどがいます。[8] : 10
ヌマリー
Numarrayと呼ばれる新しいパッケージは、Numericのより柔軟な代替として書かれました。[9] Numericと同様に、これも現在は非推奨です。[10] [11] Numarrayは大きな配列の操作は高速でしたが、小さな配列ではNumericよりも低速でした。[12]そのため、しばらくの間、両方のパッケージが異なるユースケースで並行して使用されていました。Numericの最新バージョン(v24.2)は2005年11月11日にリリースされ、numarrayの最新バージョン(v1.5.2)は2006年8月24日にリリースされました。[13]
NumericをPython標準ライブラリに組み込むという要望があったが、Guido van Rossumは、当時のコードではメンテナンスが不可能であると判断した。[いつ? ] [14]
ナンピ
2005年初頭、NumPy開発者のTravis Oliphantは、コミュニティを単一の配列パッケージに統合したいと考え、Numarrayの機能をNumericに移植し、その結果を2006年にNumPy 1.0としてリリースしました。 [9]この新しいプロジェクトはSciPyの一部でした。配列オブジェクトを取得するためだけに巨大なSciPyパッケージをインストールするのを避けるために、この新しいパッケージは分離され、NumPyと呼ばれました。Python 3のサポートは、2011年にNumPyバージョン1.5.0で追加されました。[15]
2011年、PyPyはPyPy用のNumPy APIの実装の開発を開始しました。[16] 2023年現在、NumPyとはまだ完全に互換性がありません。[17]
特徴
NumPy は、最適化されていないバイトコードインタープリタである Python のCPython リファレンス実装をターゲットにしています。このバージョンの Python 用に記述された数学アルゴリズムは、コンパイラの最適化がないため、コンパイルされた同等のアルゴリズムよりも実行速度が遅くなることがよくあります。NumPy は、多次元配列と、配列に対して効率的に動作する関数と演算子を提供することで、この速度低下の問題に部分的に対処しています。これらを使用するには、NumPy を使用して一部のコード (主に内部ループ)を書き直す必要があります。
PythonでNumPyを使用すると、両方ともインタープリタであるためMATLABに匹敵する機能が得られ、 [18]ほとんどの操作がスカラーではなく配列または行列で機能する限り、ユーザーは高速なプログラムを書くことができます。比較すると、MATLABはSimulinkに代表される多数の追加ツールボックスを誇っていますが、NumPyはより現代的で完全なプログラミング言語であるPythonと本質的に統合されています。さらに、補完的なPythonパッケージも利用できます。SciPyはMATLABに似た機能をさらに追加するライブラリであり、MatplotlibはMATLABに似たプロット機能を提供するプロットパッケージです。matlabはスパース行列演算を実行できますが、numpyだけではそのような演算を実行できないため、scipy.sparseライブラリを使用する必要があります。内部的には、MATLABとNumPyはどちらも効率的な線形代数計算 のためにBLASとLAPACKに依存しています。
広く使用されているコンピュータ ビジョンライブラリOpenCVのPythonバインディングは、NumPy 配列を使用してデータを保存および操作します。複数のチャネルを持つ画像は単純に 3 次元配列として表現されるため、他の配列を使用してインデックス付け、スライス、またはマスキングを行うことで、画像の特定のピクセルに非常に効率的にアクセスできます。画像、抽出された特徴点、フィルター カーネルなど、OpenCV の汎用データ構造としての NumPy 配列により、プログラミング ワークフローとデバッグが大幅に簡素化されます。[要出典]
重要なのは、多くのNumPy操作がグローバルインタープリタロックを解放し、マルチスレッド処理を可能にすることです。[19]
NumPyはC APIも提供しており、Pythonコードが低水準言語で書かれた外部ライブラリと相互運用できるようにします。[20]
ndarrayデータ構造
NumPyのコア機能は、n次元配列の「ndarray」データ構造です。これらの配列はメモリ上のストライドビューです。 [9] Pythonの組み込みリストデータ構造とは対照的に、これらの配列は均一な型付けです。つまり、1つの配列のすべての要素は同じ型でなければなりません。
このような配列は、 C / C++、Python、Fortranの拡張機能によってCPythonインタープリタに割り当てられたメモリバッファへのビューにもなり、データをコピーする必要もなく、既存の数値ライブラリとの互換性が得られます。この機能は、そのようなライブラリ(特にBLASとLAPACK)をラップするSciPyパッケージによって活用されています。NumPyには、メモリマップされたndarrayのサポートが組み込まれています。 [9]
制限事項
配列にエントリを挿入または追加することは、Python のリストの場合ほど簡単にはできません。配列をnp.pad(...)拡張するルーチンは、実際には、必要な形状とパディング値を持つ新しい配列を作成し、指定された配列を新しい配列にコピーして返します。NumPy のnp.concatenate([a1,a2])操作は、実際には 2 つの配列をリンクするのではなく、指定された両方の配列のエントリを順番に埋め込んだ新しい配列を返します。配列の次元を再形成できるのは、配列内の要素数が変わらない場合のみです。これらの状況は、NumPy の配列が連続したメモリ バッファーnp.reshape(...)のビューでなければならないという事実に起因しています。
ベクトル化された演算として表現できないアルゴリズムは、通常、「純粋な Python」で実装する必要があるため実行速度が遅くなります。一方、ベクトル化により、入力と同じ大きさの一時配列を作成する必要があるため、一部の演算のメモリ複雑度が定数から線形に増加する可能性があります。これらの問題を回避するために、数値コードの実行時コンパイルがいくつかのグループによって実装されています。NumPy と相互運用できるオープンソースソリューションには、numexpr [21]やNumba などがあります。[22] Cython と Pythran は、これらの静的コンパイルの代替手段です。
最近の大規模な科学計算アプリケーションの多くは、NumPy 配列の能力を超える要件を持っています。たとえば、NumPy 配列は通常、コンピュータのメモリにロードされますが、大規模なデータセットを分析するには容量が不十分な場合があります。さらに、NumPy 操作は単一のCPUで実行されます。ただし、多くの線形代数操作は、多くのディープラーニングアプリケーションが依存している CPU のクラスターまたはGPUやTPUなどの特殊なハードウェアで実行することで高速化できます。その結果、分散配列用のDaskや GPU での計算用のTensorFlowや JAXなど、科学的な Python エコシステムでは近年、いくつかの代替配列実装が登場しています。その人気により、これらはNumPy のAPIのサブセットを実装するか、それを模倣することが多く、ユーザーはコードの変更を最小限に抑えて配列実装を変更できます。[3] NvidiaのCUDAフレームワークによって加速されたCuPyというライブラリ[23]も、NumPyの「ドロップイン代替品」として、より高速なコンピューティングの可能性を示しています。[24]
例
numpyを npとして インポートします。 numpy.randomからrandをインポートします。numpy.linalgからsolveをインポートします。inv a = np.array ([[ 1 , 2 , 3 , 4 ],[ 3 , 4 , 6 , 7 ] , [ 5 , 9 , 0 , 5 ]]) a.transpose ( )
基本操作
>>> a = np . array ([ 1 , 2 , 3 , 6 ])
>>> b = np . linspace ( 0 , 2 , 4 ) # 0 から始まり 2 で終わる 4 つの等間隔の点を持つ配列を作成します。
>>> c = a - b
>>> c
array ([ 1. , 1.33333333 , 1.66666667 , 4. ])
>>> a ** 2
array ([ 1 , 4 , 9 , 36 ])
ユニバーサル機能
>>> a = np . linspace ( - np . pi , np . pi , 100 )
>>> b = np . sin ( a )
>>> c = np . cos ( a )
>>>
>>> # 関数は数値と配列の両方をパラメータとして受け取ることができます。
>>> np . sin ( 1 )
0.8414709848078965
>>> np . sin ( np . array ([ 1 , 2 , 3 ]))
array ([ 0.84147098 , 0.90929743 , 0.14112001 ])
線形代数
>>> numpy.randomから randをインポートします>>> numpy.linalgからsolveをインポートします、inv >>> a = np . array ([[ 1 , 2 , 3 ], [ 3 , 4 , 6.7 ], [ 5 , 9.0 , 5 ]]) >>> a . transpose ()配列([[ 1. , 3. , 5. ], [ 2. , 4. , 9. ], [ 3. , 6.7 , 5. ]]) >>> inv ( a )配列([[ - 2.27683616 , 0.96045198 , 0.07909605 ], [ 1.04519774 , - 0.56497175 , 0.1299435 ], [ 0.39548023 , 0.05649718 , - 0.11299435 ]]) >>> b = np . array ([ 3 , 2 , 1 ]) >>> solve ( a , b ) # 方程式 ax = b を解きますarray ([ - 4.83050847 , 2.13559322 , 1.18644068 ]) >>> c = rand ( 3 , 3 ) * 20 # [0,1] の範囲内で 20 倍された値の 3x3 ランダム行列を作成します>>> c array ([[ 3.98732789 , 2.47702609 , 4.71167924 ], [ 9.24410671 , 5.5240412 , 10.6468792 ], [ 10.38136661 , 8.44968437 , 15.17639591 ]]) >>> np . dot ( a , c ) # 行列乗算配列([[ 53.61964114 , 38.8741616 , 71.53462537
],
[ 118.4935668 , 86.14012835 , 158.40440712 ],
[ 155.04043289 , 104.3499231 , 195.26228855 ]])
>>> a @ c # Python 3.5 および NumPy 1.10 以降
array ([[ 53.61964114 , 38.8741616 , 71.53462537 ],
[ 118.4935668 , 86.14012835 , 158.40440712 ],
[ 155.04043289 , 104.3499231 , 195.26228855 ]])
多次元配列
>>> M = np . zeros ( shape = ( 2 , 3 , 5 , 7 , 11 ))
>>> T = np . transpose ( M , ( 4 , 2 , 1 , 3 , 0 ))
>>> T . shape
( 11 , 5 , 3 , 7 , 2 )
OpenCVとの統合
>>> import numpy as np
>>> import cv2
>>> r = np . reshape ( np . arange ( 256 * 256 ) % 256 ,( 256 , 256 )) # 赤色チャンネル用に 0 から 255 までの水平グラデーションを持つ 256x256 ピクセル配列
>>> g = np . zeros_like ( r ) # r と同じサイズとタイプの配列ですが、緑色チャンネル用に 0 で埋められています
>>> b = r . T # r を転置すると、青色チャンネルに垂直グラデーションが生成されます
>>> cv2 . imwrite ( 'gradients.png' , np . dstack ([ b , g , r ])) # OpenCV 画像は BGR として解釈され、深度スタックされた配列は 'gradients.png' という 8 ビット RGB PNG ファイルに書き込まれます
True
最近傍探索
反復的な Python アルゴリズムとベクトル化された NumPy バージョン。
>>> # # # 純粋な反復Python # # #
>>> points = [[ 9 , 2 , 8 ],[ 4 , 7 , 2 ],[ 3 , 4 , 4 ],[ 5 , 6 , 9 ],[ 5 , 0 , 7 ],[ 8 , 2 , 7 ],[ 0 , 3 , 2 ],[ 7 , 3 , 0 ],[ 6 , 1 , 1 ],[ 2 , 9 , 6 ]]
>>> qPoint = [ 4 , 5 , 3 ]
>>> minIdx = - 1
>>> minDist = - 1
>>> for idx , point in enumerate ( points ): # すべてのポイントを反復処理します
... dist = sum ([( dp - dq ) ** 2 for dp , dq in zip ( point , qPoint )]) ** 0.5 # 各点から q までのユークリッド距離を計算します
... dist < minDistまたはminDist < 0の場合 : # 必要に応じて、対応する点の最小距離とインデックスを更新します... minDist = dist ... minIdx = idx
>>> print ( f 'q に最も近い点: { points [ minIdx ] } ' )
qに最も近い 点 : [ 3 , 4 , 4 ]
>>> # # # 同等の NumPy ベクトル化 # # #
>>> import numpy as np
>>> points = np . array ([[ 9 , 2 , 8 ],[ 4 , 7 , 2 ],[ 3 , 4 , 4 ],[ 5 , 6 , 9 ],[ 5 , 0 , 7 ],[ 8 , 2 , 7 ],[ 0 , 3 , 2 ],[ 7 , 3 , 0 ],[ 6 , 1 , 1 ],[ 2 , 9 , 6 ]])
>>> qPoint = np . array ([ 4 , 5 , 3 ])
>>> minIdx = np . argmin ( np . linalg . norm ( points - qPoint , axis = 1 )) # すべてのユークリッド距離を一度に計算し、最小のもののインデックスを返します
>>> print ( f 'q への最も近い点: { points [ minIdx ] } ' )
qへの最も近い 点 : [ 3 4 4 ]
フリー
ネイティブコードを素早くラップしてスクリプトを高速化します。[25] [26] [27]
! Python Fortran ネイティブ コード呼び出しの例
! f2py -c -m foo *.f90
! Intent ステートメントを使用して Fortran を Python の名前付きモジュールにコンパイル
! Fortran サブルーチンのみ、関数ではありません。C ラッパーを使用した JNI よりも簡単です
! gfortran が必要で、
サブルーチンftest ( a 、b 、n 、c 、d )を作成します implicit none integer 、intent ( in ) :: a 、b 、n integer 、intent ( out ) :: c 、d integer :: i c = 0 do i = 1 、n c = a + b + c end do d = ( c * n ) * ( - 1 ) end subroutine ftest
>>> import numpy as np
>>> import foo
>>> a = foo . ftest ( 1 , 2 , 3 ) # または ac と ad の代わりに c,d =
>>> print ( a )
(9,-27)
>>> help ( 'foo.ftest' ) # foo.ftest.__doc__
参照
参考文献
- ^ 「リリース 2.2.1」。2024年12月21日。 2024年12月25日閲覧。
- ^ "NumPy — NumPy". numpy.org . NumPy 開発者。
- ^ ab チャールズ・R・ハリス; K・ジャロッド・ミルマン。ステファン・J・ファン・デル・ウォルト。他。 (2020年9月16日)。 「NumPy による配列プログラミング」(PDF)。自然。585 (7825): 357–362。arXiv : 2006.10256。土井:10.1038/S41586-020-2649-2。ISSN 1476-4687。PMC 7759461。PMID 32939066。ウィキデータ Q99413970。
- ^ 「NumFOCUS スポンサープロジェクト」。NumFOCUS 。 2021年10月25日閲覧。
- ^ 「インデックス作成 — NumPy v1.20 マニュアル」。numpy.org 。 2021年4月6日閲覧。
- ^ abc Millman, K. Jarrod; Aivazis, Michael (2011). 「科学者とエンジニアのためのPython」。Computing in Science and Engineering。13 ( 2): 9–12。Bibcode :2011CSE....13b...9M。doi :10.1109/MCSE.2011.36。2019年2月19日時点のオリジナルよりアーカイブ。 2014年7月7日閲覧。
- ^ Travis Oliphant (2007). 「Python for Scientific Computing」(PDF) . Computing in Science and Engineering . 2013-10-14 のオリジナル(PDF)からアーカイブ。2013-10-12に取得。
- ^ abcd デビッド・アッシャー;ポール・F・デュボワ。コンラッド・ヒンセン。ジム・フグニン;トラヴィス・オリファント (1999)。 「数値Python」(PDF)。
- ^ abcd ファン・デル・ウォルト、ステファン;コルベール、S.クリス。ヴァロックオー、ガエル (2011)。 「NumPy 配列: 効率的な数値計算のための構造」。科学および工学におけるコンピューティング。13 (2)。 IEEE: 22.arXiv : 1102.1523。Bibcode :2011CSE....13b..22V。土井:10.1109/MCSE.2011.37。S2CID 16907816。
- ^ 「Numarrayホームページ」。2006年6月24日閲覧。
- ^ Travis E. Oliphant (2006年12月7日). NumPyガイド. 2017年2月2日閲覧。
- ^ Travis Oliphant と他の SciPy 開発者。[Numpy-discussion] Numeric のステータス。2017年2 月 2 日閲覧。
- ^ 「NumPy Sourceforge ファイル」。2008年 3 月 24 日閲覧。
- ^ 「History_of_SciPy - SciPy wiki ダンプ」. scipy.github.io .
- ^ 「NumPy 1.5.0 リリースノート」 。 2011年4月29日閲覧。
- ^ 「PyPy ステータス ブログ: NumPy の資金調達とステータスの更新」 。2011年 12 月 22 日閲覧。
- ^ 「NumPyPy Status」。2023年12月19日閲覧。
- ^ SciPy コミュニティ。「NumPy for Matlab users」 。2017年2 月 2 日閲覧。
- ^ 「numpy リリースノート」。
- ^ McKinney, Wes (2014). 「NumPy の基礎: 配列とベクトル化計算」。Python for Data Analysis (第 1 版、第 3 版)。O'Reilly。p. 79。ISBN 978-1-449-31979-3。
- ^ Francesc Alted. 「numexpr」. GitHub . 2014年3月8日閲覧。
- ^ “Numba” . 2014年3月8日閲覧。
- ^ Shohei Hido - CuPy: GPU 用の NumPy 互換ライブラリ - PyCon 2018、2021 年 12 月 21 日にオリジナルからアーカイブ、2021 年 5 月 11 日に取得
- ^ Entschev, Peter Andreas (2019-07-23). 「シングル GPU CuPy スピードアップ」. Medium . 2021-05-11閲覧。
- ^ 「NumPy の F2PY ドキュメント」。NumPy 。2022 年4 月 18 日閲覧。
- ^ ガイ・ワーシー(2022年1月3日)。「Python対Fortranのスマックダウン」ガイ・ワーシー。ガイ・ワーシー。 2022年4月18日閲覧。
- ^ Shell, Scott. 「Python 用の高速 Fortran ルーチンの作成」(PDF) . UCSB 工学部. カリフォルニア大学サンタバーバラ校 . 2022 年4 月 18 日閲覧。
さらに読む
- マッキーニー、ウェス(2022年)。データ分析のためのPython(第3版)。オライリー。ISBN 978-1098104030。
- Bressert, Eli (2012)。Scipyと Numpy :開発者向け概要。O'Reilly。ISBN 978-1-4493-0546-8。
- VanderPlas, Jake (2016)。「NumPy 入門」。Pythonデータ サイエンス ハンドブック: データ操作に必須のツール。O'Reilly。pp. 33–96。ISBN 978-1-4919-1205-8。
外部リンク
- 公式サイト
- NumPy チュートリアル
- NumPyの歴史
