Как перебрать массив значений на заданной оси? - PullRequest
0 голосов
/ 14 февраля 2019

У меня есть ndarray формы, скажем

my_array = np.zeros((Na, Nb, Nc))

, и у меня есть Nb сгустков данных формы (Na, Nc)

Я хотел бы заполнить "my_array" моимсгустки данных следующим образом:

for b, bit in zip(range(Nb), my_bits):
    my_array[:, b, :] = bit

, но я хотел бы сделать это для любой оси произвольного набора данных произвольной формы.Как бы я это сделал?

** РЕДАКТИРОВАТЬ ** Кто-то указал на двусмысленность в моем вопросе.Ниже приведен пример кода того, что я знаю, как делать, что приводит к тому, чего я не знаю.

Что я знаю:

my_bits = [np.ones((Na, Nc)) for j in range(Nb)]
my_array = np.zeros((Na, Nb, Nc))
for b, bit in zip(range(Nb), my_bits):
    my_array[:, b, :] = bit

В общем, мы могли бы рассмотреть

my_array = np.zeros((N1, N2, ..., Nj, ..., Nmax))
bit = np.ones((N1, N2, ..., Nj-1, Nj+1, ..., Nmax))
my_bits = [bit]*Nj

Оттуда я хотел бы заполнить my_array my_bits вдоль оси Nj.Как бы я это сделал?Я смотрю на функцию nditer, но я не уверен, что с ней делать.

Ответы [ 3 ]

0 голосов
/ 15 февраля 2019

Думаю, вы захотите numpy.transpose

list_of_2d_arrays = [ make_2d_array() for i in range(Nb) ]  # each has shape=(Na,Nc)
tensor3d = np.array(list_of_2d_arrays) # shape = (Nb,Na,Nc)
# now shift the dimensions around
X = np.transpose(tensor3d,(1,0,2)) # has shape (Na,Nb,Nc)

0 голосов
/ 15 февраля 2019

Использование transpose для перемещения оси итерации в известную позицию, переднюю или последнюю, выполняется в некоторых numpy функциях.

Другой подход заключается в создании объекта slice и итерации этого,

In [46]: arr = np.zeros((2,3,4),int)
In [47]: idx = np.full((arr.ndim,), slice(None))
In [48]: n=2
In [49]: for i in range(arr.shape[n]):
    ...:     idx[n] = i
    ...:     arr[tuple(idx)] = i+1
    ...:     
In [50]: arr
Out[50]: 
array([[[1, 2, 3, 4],
        [1, 2, 3, 4],
        [1, 2, 3, 4]],

       [[1, 2, 3, 4],
        [1, 2, 3, 4],
        [1, 2, 3, 4]]])

для другой оси

In [56]: arr = np.zeros((2,3,4),int)
In [57]: idx = np.full((arr.ndim,), slice(None))
In [58]: n=1
In [59]: for i in range(arr.shape[n]):
    ...:     idx[n] = i
    ...:     arr[tuple(idx)] = i+1
    ...:     
In [60]: arr
Out[60]: 
array([[[1, 1, 1, 1],
        [2, 2, 2, 2],
        [3, 3, 3, 3]],

       [[1, 1, 1, 1],
        [2, 2, 2, 2],
        [3, 3, 3, 3]]])

В этом случае idx изменяется следующим образом:

[slice(None, None, None) 0 slice(None, None, None)]
[slice(None, None, None) 1 slice(None, None, None)]
[slice(None, None, None) 2 slice(None, None, None)]

Ключ в том, что индексное выражение имеет кортежный эквивалент, который может быть построен программно:

In [61]: np.s_[:,3,:]
Out[61]: (slice(None, None, None), 3, slice(None, None, None))
0 голосов
/ 15 февраля 2019

Здесь проблема с размерами.Если я правильно понял, my_array[:, 0, :] - это то же измерение, что и my_bits.Таким образом, назначение должно быть сделано так:

import numpy as np

Na = 2
Nb = 2
Nc = 2
my_array = np.zeros((Na, Nb, Nc))

my_bits = np.ones((Na, Nc))

print('my_array before', my_array)

for b in range(Nb):
  my_array[:, b, :] = my_bits

print('my_array after', my_array)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...