2016-10-12 23 views
0

numpyを試してみたところ、この奇妙な動作が見つかりました。 このコードはうまく動作:Python numpy配列整数のインデックス付きフラットスライスの割り当て

>>> a = np.array([[1, 2, 3], [4, 5, 6]])  
>>> a[:, 1].flat[:] = np.array([-1, -1]) 
>>> a 
array([[ 1, -1, 3], 
     [ 4, -1, 6]]) 

しかし、このコードは、0の-1の要素と2列に変更されませんなぜですか?

>>> a[:, [0, 2]].flat[:] = np.array([-1, -1]) 
>>> a 
array([[ 1, -1, 3], 
     [ 4, -1, 6]]) 

そして、このように0と2列の-1要素に変更されるようにコードを書く方法は?

UPD:flatまたはSMTに類似の使用は、私の例では、必ずしも

UPD2です:私はこのコードに基づか問題の例を作った:

img = imread(img_name) 
xor_mask = np.zeros_like(img, dtype=np.bool) 
# msg_bits looks like array([ True, False, False, ..., False, False, True], dtype=bool) 
xor_mask[:, :, channel].flat[:len(msg_bits)] = np.ones_like(msg_bits, dtype=np.bool) 

と割り当てた後、チャンネルでマスクをXORする== 0または1または2のコードは正常に機能しますが、channel == [1,2]またはsmtのような場合は代入が行われません

+0

「フラット」を使用する必要があるのはなぜか分かりません。既に下記で解説したように、 'flat'はコピーを作成して、更新が元の配列を変更しない可能性があります。なぜあなたは 'フラット'を必要としているのかを解説し、おそらく解決策を得ることができます。 – lbolla

+0

@lbolla更新された質問 – KgOfHedgehogs

+1

@ЮраМахоткинあなたは['XY問題'](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)にこだわっているようです。 – Divakar

答えて

1

他の人が指摘しているように、.flatは元のベクトルのコピーを作成する可能性があるため、その更新は失われます。しかし、flatは1Dスライスを調整しているので、forループを使用して複数のインデックスを更新することができます。あなたがflat[:]を使用する必要はありません

import numpy as np 

a = np.array([[1, 2, 3], [4, 5, 6]]) 
a[:, 1].flat = np.array([-1, -1]) 
print a 

# Use for loop to avoid copies 
for idx in [0, 2]: 
    a[:, idx].flat = np.array([-1, -1]) 
print a 

注:ちょうどflat十分な(そしておそらくより効率的)です。

+0

私の問題を解決するにはループだけですか? – KgOfHedgehogs

+0

何が好きではないですか? – lbolla

+0

何もありませんが、私はこのような状況のためにnumpyを学んでいて、いくつかのnumpyの構築を期待しています – KgOfHedgehogs

2

最初の例では、スライスを平坦化しても形状は変わらず、実際には Python Numpyは新しいオブジェクトを作成しません。フラット化されたスライスに割り当てることは、実際のスライスに割り当てることに似ています。しかし、2次元配列を平坦化すると、形状が変わり、numpyがそのコピーを作成します。あなただけのflat[:]from a[:, [0, 2]].flat[:] += 100を削除することができ

In [5]: a[:, [0, 2]] += 100 

In [6]: a 
Out[6]: 
array([[101, 2, 103], 
     [104, 5, 106]]) 
+0

この例は他の問題から、必ず「フラット」を使用する必要があります。 「フラット」のやり方について説明できますか? – KgOfHedgehogs

+0

@ЮраМахоткинプレースは質問にユースケースを追加しますが、このように答えるのは難しいです。 – Kasramvd

0

も、あなたはそれに追加するには、スライスを平らにする必要はありません

>>> import numpy as np 
>>> a = np.array([[1, 2, 3], [4, 5, 6]]) 
>>> a[:, 1].flat[:] += 100 
>>> a 
array([[ 1, 102, 3], 
     [ 4, 105, 6]]) 
>>> a[:, [0, 2]] += 100 
>>> a 
array([[101, 102, 103], 
     [104, 105, 106]]) 

しかし、あなたはそれが必要であると言います... flatではなく、最初の配列に追加しようとしているものは何でもreshapeできませんか?

それを最初に戻って参照しながら、第2の指標呼び出しは、配列のコピーを作成します:あなたがflat manerの際、反復処理したいときの要素は、隣接するnumpyのを作るていないことが表示されます

>>> import numpy as np 
>>> a = np.array([[1, 2, 3], [4, 5, 6]]) 
>>> b = a[:,1].flat 
>>> b[0] += 100 
>>> a 
array([[ 1, 102, 3], 
     [ 4, 5, 6]]) 
>>> b =a[:,[0,2]].flat 
>>> b[0] 
1 
>>> b[0] += 100 
>>> a 
array([[ 1, 102, 3], 
     [ 4, 5, 6]]) 
>>> b[:] 
array([101, 3, 4, 6]) 

配列のコピーに対するイテレータ。

関連する問題