派手な配列の一部の次元のみを平坦化する方法


127

派手な配列の最初の次元の一部だけを「サブフラット化」またはフラット化する簡単な方法はありますか?

たとえば、次元の数の多い配列が与えられた(50,100,25)場合、結果の次元は次のようになります。(5000,25)



numpy ndarray配列のスライスに関する復習コースが必要です。多次元配列インデックスとも呼ばれます:docs.scipy.org/doc/numpy-1.13.0/reference/arrays.indexing.html 配列は、角括弧を使用してndarrayをスライスし、カンマ区切りを使用してそれぞれの量を区切りますあなたが望む次元。これは(正確ではありませんが)次のようになります。your_array[50:100, 7, :]これは、2番目の次元にスライス番号7のみを使用して、3dオブジェクトを2dに平坦化します。
Eric Leschinski、2017

回答:


129

numpy.reshapeを見てください

>>> arr = numpy.zeros((50,100,25))
>>> arr.shape
# (50, 100, 25)

>>> new_arr = arr.reshape(5000,25)
>>> new_arr.shape   
# (5000, 25)

# One shape dimension can be -1. 
# In this case, the value is inferred from 
# the length of the array and remaining dimensions.
>>> another_arr = arr.reshape(-1, arr.shape[-1])
>>> another_arr.shape
# (5000, 25)

81

Alexanderの答えを少し一般化すると、np.reshapeは-1を引​​数として取ることができます。これは、「配列の合計サイズを、リストされている他のすべての次元の積で割った値」を意味します。

たとえば、最後の次元を除くすべてを平坦化するには:

>>> arr = numpy.zeros((50,100,25))
>>> new_arr = arr.reshape(-1, arr.shape[-1])
>>> new_arr.shape
# (5000, 25)

33

Peterの回答を少し一般化します。3次元配列を超えて移動したい場合は、元の配列の形状の範囲を指定できます。

たとえば、最後の2つの次元を除くすべてを平坦化するには:

arr = numpy.zeros((3, 4, 5, 6))
new_arr = arr.reshape(-1, *arr.shape[-2:])
new_arr.shape
# (12, 5, 6)

編集:私の以前の答えを少し一般化します-もちろん、変形の最初に範囲を指定することもできます:

arr = numpy.zeros((3, 4, 5, 6, 7, 8))
new_arr = arr.reshape(*arr.shape[:2], -1, *arr.shape[-2:])
new_arr.shape
# (3, 4, 30, 7, 8)

2
もう2年以上になります...もう少し一般化する必要があります!;)
Lith

1

別のアプローチは次のように使用するnumpy.resize()ことです:

In [37]: shp = (50,100,25)
In [38]: arr = np.random.random_sample(shp)
In [45]: resized_arr = np.resize(arr, (np.prod(shp[:2]), shp[-1]))
In [46]: resized_arr.shape
Out[46]: (5000, 25)

# sanity check with other solutions
In [47]: resized = np.reshape(arr, (-1, shp[-1]))
In [48]: np.allclose(resized_arr, resized)
Out[48]: True
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.