1

次のコードがなぜそのように動作するのか理解できません。

import numpy as np


nbr_arrays = 4
nbr_fields_per_array = 3
nbr_subfields_per_field = 2

# pre-allocate zeros list
zeros = np.zeros(nbr_subfields_per_field)

data = []
for array in range(nbr_arrays):

    # pre-allocate the subarray 
    empty_array = []
    for empty_array_index in range(nbr_fields_per_array):
        empty_array.append(zeros)

    # append pre subarray to data
    data.append(empty_array)

    # fill up data
    for j in range(nbr_fields_per_array):
        for k in range(nbr_subfields_per_field):
            data[array][j][k] = j*k*array

生成された出力は次のdataようになります。

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

zeros完全に異なって読むことさえ:

array([ 0.,  6.])

さまざまなリストのIDを見ると、次のようになります。

id(data[0][0])
Out[72]: 45790208

id(data[1][0])
Out[66]: 45790208

id(data[2][0])
Out[67]: 45790208

id(data[3][0])
Out[68]: 45790208

id(zeros)
Out[69]: 45790208

なぜすべての参照が同じなのですか?そして、なぜzero突然ゼロ以外の値が含まれるのですか?

誰かがここで何が起こっているのか、そして期待される動作(出力)を確認するためにコードをどのように変更する必要があるのか​​を誰かが私に説明してくれれば本当にありがたいです。

編集:

使用せず、代わりにzeros使用[[0]*nbr_subfields_per_field for x in range(nbr_fields_per_array)]すると、期待どおりの結果が得られます。しかし、なぜ?元のコードが機能しないのはなぜですか?動作する変更されたコード:

data = []
for array in range(nbr_arrays):
    empty_array = [[0]*nbr_subfields_per_field for x in range(nbr_fields_per_array)]

    ''' this is causing the weird behaviour 
    empty_array = []
    for empty_array_index in range(nbr_fields_per_array):
        empty_array.append(zeros)
    '''

    data.append(empty_array)

    for j in range(nbr_fields_per_array):
        for k in range(nbr_subfields_per_field):
            data[array][j][k] = j*k*array
4

2 に答える 2

1
# pre-allocate zeros list
zeros = np.zeros(nbr_subfields_per_field)

これにより、単一のオブジェクトが作成されます。

for empty_array_index in range(nbr_fields_per_array):
    empty_array.append(zeros)

これにより、同じオブジェクトが追加され続けます。

事前割り当てを停止します。

于 2012-05-23T23:07:20.347 に答える
0

Numpyは、必要に応じて多次元配列を設定できます。配列を作成した直後に配列全体を初期化するので、このempty方法が最も適切であるように思われます。

data = np.empty((nbr_arrays, nbr_fields_per_array, nbr_subfields_per_field))
于 2012-05-23T23:44:39.540 に答える