[解決済み] 連続配列と非連続配列の違いは何ですか?
質問
この質問では numpyマニュアル には、reshape()関数について、次のように書かれています。
>>> a = np.zeros((10, 2))
# A transpose make the array non-contiguous
>>> b = a.T
# Taking a view makes it possible to modify the shape without modifying the
# initial object.
>>> c = b.view()
>>> c.shape = (20)
AttributeError: incompatible shape for a non-contiguous array
私の質問です。
- 連続配列と非連続配列とは何ですか?C言語の連続したメモリブロックのようなものでしょうか? 連続したメモリブロックとは何ですか?
- この 2 つの間にパフォーマンスの違いはありますか。どのような場合にどちらかを使うべきでしょうか?
- なぜ転置は配列を非連続にするのですか?
-
なぜ
c.shape = (20)
はエラーを投げますincompatible shape for a non-contiguous array
?
ご回答ありがとうございました。
どのように解決するのですか?
連続配列は、切れ目のないメモリブロックに格納された配列にすぎません。配列の次の値にアクセスするには、次のメモリアドレスに移動するだけです。
2次元配列
arr = np.arange(12).reshape(3,4)
. このようになります。
コンピュータのメモリ内には
arr
はこのように格納されます。
これはつまり
arr
は
Cの連続した
配列であるため
行
は連続したメモリブロックとして格納されるからです。次のメモリアドレスは、その行の次の行の値を保持しています。列を下に移動したい場合は、3 つのブロックを飛び越えるだけです (たとえば、0 から 4 に移動するには、1、2、3 を飛び越えることになります)。
での配列の転置は
arr.T
で転置すると、隣接する行のエントリが隣接するメモリアドレスに存在しなくなるため、C の連続性が失われることを意味します。しかし
arr.T
は
Fortranの連続した
であるため
列
はメモリの連続したブロックにあるためです。
パフォーマンス面では、互いに隣接するメモリ アドレスへのアクセスは、より広がっているアドレスへのアクセスよりも高速であることが非常に多いです (RAM から値をフェッチするには、多数の隣接するアドレスをフェッチして CPU にキャッシュする必要があります)。これは、連続した配列に対する操作がより速くなることが多いことを意味します。
C の連続したメモリ レイアウトの結果として、行単位の操作は列単位の操作よりも通常高速になります。例えば、通常
np.sum(arr, axis=1) # sum the rows
の方が若干速いです。
np.sum(arr, axis=0) # sum the columns
同様に、Fortranの連続配列の場合、列に対する操作は若干速くなります。
最後に、なぜFortran連続配列は新しい形状を割り当てることによって平坦化できないのでしょうか?
>>> arr2 = arr.T
>>> arr2.shape = 12
AttributeError: incompatible shape for a non-contiguous array
これを可能にするために、NumPy は、行を
arr.T
をこのようにまとめる必要があります。
(設定することで
shape
属性を直接指定すると、C言語の順序を仮定します - つまり、NumPyは行単位で操作を実行しようとします)。
これは不可能です。どんな軸でも、NumPyには
定数
のストライド長(移動するバイト数)が必要です。平坦化
arr.T
をこのように平らにすると、配列の連続した値を取得するために、メモリ内で前方や後方にスキップする必要があります。
もし私たちが
arr2.reshape(12)
と書くと、NumPy は arr2 の値を新しいメモリブロックにコピーします(このシェイプの元のデータに対するビューを返すことができないため)。
関連
-
[解決済み】TypeErrorの修正方法。Unicodeオブジェクトは、ハッシュ化する前にエンコードする必要がある?
-
[解決済み] staticmethodとclassmethodの違いについて
-
[解決済み] Pythonのリストメソッドであるappendとextendの違いは何ですか?
-
[解決済み] 最小限の驚き」と「変更可能なデフォルトの引数
-
[解決済み] パラメータに**(ダブルスター/アスタリスク)、*(スター/アスタリスク)がありますが、これはどういう意味ですか?
-
[解決済み] JavaScriptで2つの配列の差を取得する方法は?
-
[解決済み】__str__と__repr__の違いは何ですか?
-
[解決済み】venv, pyvenv, pyenv, virtualenv, virtualenvwrapper, pipenvなどの違いは何ですか?
-
[解決済み】type()とisinstance()の違いは何ですか?)
-
[解決済み】Djangoでnull=Trueとblank=Trueの違いは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
ピローによる動的キャプチャ認識のためのPythonサンプルコード
-
Python関数の高度な応用を解説
-
Pythonによるjieba分割ライブラリ
-
pyCaret効率化乗算器 オープンソース ローコード Python機械学習ツール
-
Python入門 openを使ったファイルの読み書きの方法
-
[解決済み】DataFrameのコンストラクタが正しく呼び出されない!エラー
-
[解決済み】 AttributeError("'str' object has no attribute 'read'")
-
[解決済み】ValueError: xとyは同じサイズでなければならない
-
[解決済み] pandasの一意な値複数の列
-
[解決済み] pytorchのreshapeとviewの違いは何ですか?