派手な配列を見ますか?


90

2D numpy配列があります。最初のk行とすべての列を含むビューを作成する方法はありますか?

重要なのは、基になるデータのコピーを回避することです(配列が大きすぎるため、部分的なコピーを作成することはできません)。

回答:


226

もちろん、通常どおりにインデックスを作成してください。たとえば、y = x[:k, :] これはビューを元の配列に戻します。データはコピーされず、加えられた更新はy反映されx、その逆も同様です。


編集:

私は通常、uint8の10GBを超える3D配列で作業するので、これについては非常に心配しています...いくつかのことを覚えておくと、Numpyはメモリ管理で非常に効率的です。メモリ内に配列のコピーを作成しないようにするためのいくつかのヒントを次に示します。

使用+=-=*=、などの配列のコピーを作成することを避けるために。たとえば、コピーを作成してそれを変更しx += 10ながら、アレイを所定の位置にx = x + 10変更します。(また、numexprを見てください

あなたがコピーを作成したい場合はx = x + 10、その意識するx = x + 10.0原因になりますxがまだなかった場合、自動的に浮動小数点アレイにアップキャストされます。しかし、x += 10.0ここで、x整数配列であり、原因となる10.0代わりに、アレイと同じ精度のINTにダウンキャストします。

さらに、多くのnumpy関数はoutパラメーターnp.abs(x, x)を取るため、xインプレースの絶対値を取得するなどのことができます。


第二編集として、ここにいくつかのより多くのヒントだ景色コピー numpyのアレイとは:

Pythonリストとは異なりy = x[:]、コピーを返さず、ビューを返します。コピーが必要な場合(もちろん、使用しているメモリの量が2倍になります)を使用します。y = x.copy()

numpy配列の「ファンシーインデックス」についてよく耳にします。リスト(または整数配列)をインデックスとして使用することは、「ファンシーインデックス」です。これは非常に便利ですが、データをコピーします。

この例として、y = x[[0, 1, 2], :]コピーを返しますy = x[:3,:]が、ビューを返します。

のような本当にクレイジーなインデックス作成でもx[4:100:5, :-10:-1, None]「通常の」インデックス作成でビューが返されるので、大きな配列であらゆる種類のスライストリックを使用することをためらわないでください。

x.astype(<dtype>)x.view(<dtype>)ビューを返し、データのコピーを新しいタイプとして返します。

ただし、これには注意してください。非常に強力で便利ですが、基になるデータがメモリに格納される方法を理解する必要があります。floatの配列があり、それらをintとして表示する場合(またはその逆)、numpyは配列の基になるビットをintとして解釈します。

たとえば、これは、1.0リトルエンディアンのシステムでは64ビットの浮動小数点が460718241880001740864ビットのintとして表示される場合[ 0, 0, 0, 0, 0, 0, 240, 63]と、uint8として表示される場合の配列になることを意味します。これは、大きな配列でビットソートを行う必要がある場合に非常に便利ですが、メモリバッファーの解釈方法を低レベルで制御できます。


とても良いヒントをありがとう!私はNumpyユーザーガイドを読んでいて、なぜx[np.array([1, 1, 3, 1])] += 1変更されたかを混乱させましたx。今それを手に入れました!
tnq177 2015

素敵なヒント!別の質問があります。numpyがコピーではなくビューをトリガーすることを証明するにはどうすればよいですか?pythonのid()はこれができないようです。
wuhaochi 2017年

3
@wuhaochiのbビューの場合a、その後にb.base is aなりますTrue。(任意の配列の)コピーは常に持っていますarr_copy.base is None
ユルク・マーリンSpaak
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.