2016-03-02 11 views
16

numpyのバージョン1.5.0でPython 2.6.6を使用して2次元numpy配列に0を埋め込む方法を知りたいと思います。ごめんなさい!しかし、これは私の限界です。したがって、np.padは使用できません。例えば、aに0を付けて、その形がbに一致するようにしたいとします。私はこれをしたい理由は、私にできるそうですが、これはかなり醜いようだpython numpy配列に0を埋め込む方法

b-a 

>>> a 
array([[ 1., 1., 1., 1., 1.], 
     [ 1., 1., 1., 1., 1.], 
     [ 1., 1., 1., 1., 1.]]) 
>>> b 
array([[ 3., 3., 3., 3., 3., 3.], 
     [ 3., 3., 3., 3., 3., 3.], 
     [ 3., 3., 3., 3., 3., 3.], 
     [ 3., 3., 3., 3., 3., 3.]]) 
>>> c 
array([[1, 1, 1, 1, 1, 0], 
     [1, 1, 1, 1, 1, 0], 
     [1, 1, 1, 1, 1, 0], 
     [0, 0, 0, 0, 0, 0]]) 

私が追加され、これをやって考えることができる唯一の方法であること。場合によってはb.shapeを使用したクリーナーソリューションがありますか?

編集、 MSeifertsの回答ありがとうございます。私は少しそれをクリーンアップする必要がありましたが、これは私が得たものである:

def pad(array, reference_shape, offsets): 
    """ 
    array: Array to be padded 
    reference_shape: tuple of size of ndarray to create 
    offsets: list of offsets (number of elements must be equal to the dimension of the array) 
    will throw a ValueError if offsets is too big and the reference_shape cannot handle the offsets 
    """ 

    # Create an array of zeros with the reference shape 
    result = np.zeros(reference_shape) 
    # Create a list of slices from offset to offset + shape in each dimension 
    insertHere = [slice(offsets[dim], offsets[dim] + array.shape[dim]) for dim in range(array.ndim)] 
    # Insert the array in the result at the specified offsets 
    result[insertHere] = array 
    return result 
+0

パディングなしでやる方法を提案できますか? – purpletentacle

答えて

44

は非常に簡単、あなたが基準形状を使用してゼロを含む配列を作成します。

result = np.zeros(b.shape) 
# actually you can also use result = np.zeros_like(b) 
# but that also copies the dtype not only the shape 

、その後どこ配列を挿入します

result[:a.shape[0],:a.shape[1]] = a 

を出来上がり、あなたはそれを埋めています:あなたはそれを必要

print(result) 
array([[ 1., 1., 1., 1., 1., 0.], 
     [ 1., 1., 1., 1., 1., 0.], 
     [ 1., 1., 1., 1., 1., 0.], 
     [ 0., 0., 0., 0., 0., 0.]]) 

また、あなたの左上の要素が

result = np.zeros_like(b) 
x_offset = 1 # 0 would be what you wanted 
y_offset = 1 # 0 in your case 
result[x_offset:a.shape[0]+x_offset,y_offset:a.shape[1]+y_offset] = a 
result 

array([[ 0., 0., 0., 0., 0., 0.], 
     [ 0., 1., 1., 1., 1., 1.], 
     [ 0., 1., 1., 1., 1., 1.], 
     [ 0., 1., 1., 1., 1., 1.]]) 

を挿入すべき場所を定義した場合、それはもう少し一般的にするが、その後、あなたが許可されるよりも大きなオフセットを持っていないことに注意してくださいすることができます。たとえば x_offset = 2の場合、これは失敗します。


任意の数のディメンションがある場合は、元の配列を挿入するスライスのリストを定義できます。私はちょっと遊んで面白かったし、配列と参照が同じ数の次元を持ち、オフセットが大きすぎない限り、任意の形状の配列を(オフセット付きで)パディングできるパディング関数を作成しました。

def pad(array, reference, offsets): 
    """ 
    array: Array to be padded 
    reference: Reference array with the desired shape 
    offsets: list of offsets (number of elements must be equal to the dimension of the array) 
    """ 
    # Create an array of zeros with the reference shape 
    result = np.zeros(reference.shape) 
    # Create a list of slices from offset to offset + shape in each dimension 
    insertHere = [slice(offset[dim], offset[dim] + array.shape[dim]) for dim in range(a.ndim)] 
    # Insert the array in the result at the specified offsets 
    result[insertHere] = a 
    return result 

そして、いくつかのテストケース:

import numpy as np 

# 1 Dimension 
a = np.ones(2) 
b = np.ones(5) 
offset = [3] 
pad(a, b, offset) 

# 3 Dimensions 

a = np.ones((3,3,3)) 
b = np.ones((5,4,3)) 
offset = [1,0,0] 
pad(a, b, offset) 
+0

ああとてもいいです。これは1d配列またはnd配列に一般化できますか? – user2015487

+0

@ user2015487 - あなたは任意の次元を受け入れるか、それとも他の次元の次元だけを受け入れる関数を意味しますか? – MSeifert

4

私はあなたの主な問題は、あなたがd=b-aを計算する必要がありますが、あなたの配列が異なるサイズを持っていることであることを理解しています。あなたは、パディングなしでこの問題を解決することができ、中間パッド入りc

の必要はありません。

import numpy as np 

a = np.array([[ 1., 1., 1., 1., 1.], 
       [ 1., 1., 1., 1., 1.], 
       [ 1., 1., 1., 1., 1.]]) 

b = np.array([[ 3., 3., 3., 3., 3., 3.], 
       [ 3., 3., 3., 3., 3., 3.], 
       [ 3., 3., 3., 3., 3., 3.], 
       [ 3., 3., 3., 3., 3., 3.]]) 

d = b.copy() 
d[:a.shape[0],:a.shape[1]] -= a 

print d 

出力:

[[ 2. 2. 2. 2. 2. 3.] 
[ 2. 2. 2. 2. 2. 3.] 
[ 2. 2. 2. 2. 2. 3.] 
[ 3. 3. 3. 3. 3. 3.]] 
+0

実際、彼の具体的なケースでは、必ずしもパッドする必要はありませんが、それはパディングとアプローチが同等の非常に少数の算術演算の1つです。それでもいい答えです! – MSeifert

20

np.padが追加されました)numpyの1.7は今かなり古いです(それは2013年にリリースされた)ので、その機能を持たない方法を尋ねた質問でも、np.padを使用してその達成方法を知ることは有用であると考えました。

それは実際にはかなり簡単です:この場合

>>> import numpy as np 
>>> a = np.array([[ 1., 1., 1., 1., 1.], 
...    [ 1., 1., 1., 1., 1.], 
...    [ 1., 1., 1., 1., 1.]]) 
>>> np.pad(a, [(0, 1), (0, 1)], mode='constant') 
array([[ 1., 1., 1., 1., 1., 0.], 
     [ 1., 1., 1., 1., 1., 0.], 
     [ 1., 1., 1., 1., 1., 0.], 
     [ 0., 0., 0., 0., 0., 0.]]) 

私は0mode='constant'のデフォルト値であることを使用。しかし、また、明示的にそれを渡すことによって指定することができます。

>>> np.pad(a, [(0, 1), (0, 1)], mode='constant', constant_values=0) 
array([[ 1., 1., 1., 1., 1., 0.], 
     [ 1., 1., 1., 1., 1., 0.], 
     [ 1., 1., 1., 1., 1., 0.], 
     [ 0., 0., 0., 0., 0., 0.]]) 

第二引数([(0, 1), (0, 1)]が)混乱思わ念のために:(この場合はタプルで)リストの各項目は、その中の寸法や項目に対応するパディングを表し(第2要素)の後にとなる。場合

>>> np.pad(a, (0, 1), mode='constant') 
array([[ 1., 1., 1., 1., 1., 0.], 
     [ 1., 1., 1., 1., 1., 0.], 
     [ 1., 1., 1., 1., 1., 0.], 
     [ 0., 0., 0., 0., 0., 0.]]) 

パディングをする前と後:だから:一つはまた、わずか2組を渡すことができるようにこの場合

[(0, 1), (0, 1)] 
     ^^^^^^------ padding for second dimension 
^^^^^^-------------- padding for first dimension 

    ^------------------ no padding at the beginning of the first axis 
    ^--------------- pad with one "value" at the end of the first axis. 

第一及び第二軸のパディングは、同一であります同じであっても(ただし、この場合は適用されません)タプルを省略することができ1:

>>> np.pad(a, 1, mode='constant') 
array([[ 0., 0., 0., 0., 0., 0., 0.], 
     [ 0., 1., 1., 1., 1., 1., 0.], 
     [ 0., 1., 1., 1., 1., 1., 0.], 
     [ 0., 1., 1., 1., 1., 1., 0.], 
     [ 0., 0., 0., 0., 0., 0., 0.]]) 

それとも前と後のパディングが軸に対して同一であるが異なる場合、あなたはまた、二番目の引数を省略することができ内側のタプルで:それは間違いを犯すのは簡単にだけだから(NumPysの期待は、あなたの意図と異なる場合)

>>> np.pad(a, [(1,), (2,)], mode='constant') 
array([[ 0., 0., 0., 0., 0., 0., 0., 0., 0.], 
     [ 0., 0., 1., 1., 1., 1., 1., 0., 0.], 
     [ 0., 0., 1., 1., 1., 1., 1., 0., 0.], 
     [ 0., 0., 1., 1., 1., 1., 1., 0., 0.], 
     [ 0., 0., 0., 0., 0., 0., 0., 0., 0.]]) 

しかし私は、常に明示的なものを使用することを好む傾向にある:

ここ
>>> np.pad(a, [1, 2], mode='constant') 
array([[ 0., 0., 0., 0., 0., 0., 0., 0.], 
     [ 0., 1., 1., 1., 1., 1., 0., 0.], 
     [ 0., 1., 1., 1., 1., 1., 0., 0.], 
     [ 0., 1., 1., 1., 1., 1., 0., 0.], 
     [ 0., 0., 0., 0., 0., 0., 0., 0.], 
     [ 0., 0., 0., 0., 0., 0., 0., 0.]]) 

NumPyは、各軸の前に1つの要素と2つの要素ですべての軸を埋めたいと思っています!軸1に1要素、軸2に2要素をパッドすることを意図していましたが、

私はパディングにタプルのリストを使用しましたが、これは単なる「マイコンベンション」です。リストのリストタプルのタプル、または配列のタプルを含むことがあります。 NumPyは、引数の長さ(または長さがない場合)と各項目の長さ(または長さがある場合)をチェックします。

0

ケースでは、配列に1秒のフェンスを追加する必要があります。

mat = np.zeros((4,4), np.int32) mat array([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]) mat[0,:] = mat[:,0] = mat[:,-1] = mat[-1,:] = 1 mat array([[1, 1, 1, 1], [1, 0, 0, 1], [1, 0, 0, 1], [1, 1, 1, 1]])

ありがとうございました。

関連する問題