Сначала заметка о конструкции массива. Массив имеет базовую c информацию, такую как shape
, dtype
и strides
, и 1d data buffer
, где хранятся фактические значения.
Копия будет новым объектом массива, со своими собственными значениями.
Представление - это новый объект массива со своими собственными shape
, et c, но он разделяет data buffer
с исходным массивом. В качестве меры эффективности, numpy
пытается сделать вид, где это возможно. Многие операции делают это, например reshape
и transpose
. Индексация также может сделать представление. basic indexing
со скаляром или срезом создает представление, advanced indexing
со списками, масками или массивами создает копию.
X.copy()
является одним из способов принудительного копирования. np.array(X)
также делает копию - если используется параметр по умолчанию copy
.
In [113]: foo = np.array([[1., 2., 3.], [4., 5., 6.], [7., 8., 9.]])
Итерация в 2d массиве, как и вы, выбирает последовательные «строки», каждая из которых представляет:
In [114]: for row in foo:
...: row[1] += 10 # modify the 2nd element of the row
...:
In [115]: foo
Out[115]:
array([[ 1., 12., 3.],
[ 4., 15., 6.],
[ 7., 18., 9.]])
Выбор строки по скалярному индексу делает то же самое:
In [116]: foo[0]
Out[116]: array([ 1., 12., 3.])
In [117]: foo[0][1:]-=10
In [118]: foo
Out[118]:
array([[ 1., 2., -7.],
[ 4., 15., 6.],
[ 7., 18., 9.]])
In [119]: foo[0,1:]
Out[119]: array([ 2., -7.])
Становится знакомым с тем, когда вы получаете представление и когда копия является важной частью обучения numpy
.
Таким образом, используя copy
, чтобы сделать копию 1-й строки:
In [124]: foo = np.array([[1., 2., 3.], [4., 5., 6.], [7., 8., 9.]])
In [126]: sum = foo[0,1:].copy()
...: for row in foo[1:]: # iterate on a slice (skips 1st row)
...: sum += row[1:] # select a slice of row (skips 1st element)
In [127]: foo # no change
Out[127]:
array([[1., 2., 3.],
[4., 5., 6.],
[7., 8., 9.]])
In [128]: sum
Out[128]: array([15., 18.])
Но мы могли бы также взять эту сумму без итерации:
In [129]: foo[:, 1:].sum(axis=0) # select slice of columns, sum across rows
Out[129]: array([15., 18.])
Лучший способ написать [126] итерацию (и, вероятно, близкую к тому, что sum
реализует в скомпилированном коде):
In [200]: res = np.zeros(2, float)
In [201]: for row in foo:
...: res += row[1:]
...:
In [202]: res
Out[202]: array([15., 18.])