NumPy нарезка на переменный размер, многомерный массив - PullRequest
0 голосов
/ 23 марта 2020

Предположим, есть следующие строки кода

import numpy as np

# The values equal to 1 inside this nested list indicate where the data need to be loaded. a = [7 x 6]
a = [
    [0, 1, 0, 1, None, None],
    [0, 0, 0, 0, None, 0],
    [0, 0, 1, 0, None, 0],
    [0, 1, 0, 1, None, 1],
    [0, 0, 0, 1, None, 0],
    [0, 0, 0, 0, None, 0],
    [1, 0, 0, 0, None, None]
]
# The list "a" cannot be modified for a number of reasons, so I create a np.array copy, named "b"
b = np.array(a)

N = int(1E7)  # Number of samples

# The loop below retrieves the positions inside "b" in which data need to be loaded
row = []
col = []
for i in range(len(b)):
    col.append([])
    if any(b[i] == 1):
        row.append(i)
    for j in range(len(a[i])):
        if b[i][j] is 1:
            b[i][j] = np.zeros((N, 1))
            col[i].append(j)


# Loading the data inside the selected positions of "b". "mydata" is a numpy array, whose shape is (N, 6)
for i in row:
    mydata = np.random.randn(N, len(a[0])).reshape(N, len(a[0])) # Generation of dummy data
    b[i, col[i]] = mydata[:, col[i]]  # This instruction returns a ValueError

Однако я получаю следующую ошибку: ValueError: несоответствие формы: массив значений формы (10000000,2) не может быть передан для индексации результата формы (2,)

Почему этот тип нарезки не работает должным образом? Это связано с переменным размером элементов массива внутри "b"?

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 23 марта 2020

Давайте уменьшим N до чего-то рационального и добавим несколько отпечатков:

print(row)
print(col)
print(a)
print(b)

Прогон:

0942:~/mypy$ python3 stack60813103.py 
[0, 2, 3, 4, 6]
[[1, 3], [], [2], [1, 3, 5], [3], [], [0]]
[[0, 1, 0, 1, None, None], [0, 0, 0, 0, None, 0], [0, 0, 1, 0, None, 0], [0, 1, 0, 1, None, 1], [0, 0, 0, 1, None, 0], [0, 0, 0, 0, None, 0], [1, 0, 0, 0, None, None]]
[[0 array([[0.],
       [0.],
       [0.],
       [0.],
       [0.]]) 0
  array([[0.],
       [0.],
       [0.],
       [0.],
       [0.]]) None
  None]
 [0 0 0 0 None 0]
 [0 0 array([[0.],
       [0.],
       [0.],
       [0.],
       [0.]]) 0
  None 0]
 ....
 [0 0 0 0 None 0]
 [array([[0.],
       [0.],
       [0.],
       [0.],
       [0.]]) 0 0 0
  None None]]
Traceback (most recent call last):
  File "stack60813103.py", line 38, in <module>
    b[i, col[i]] = mydata[:, col[i]]  # This instruction returns a ValueError
ValueError: shape mismatch: value array of shape (5,2) could not be broadcast to indexing result of shape (2,)

row, col и a являются списками, b является массивом типа dtype (из-за всех None). Ваш l oop вставил кучу np.zeros((N,1)) массивов.

mydata - это (N, 5) массив с плавающей точкой.

mydata[:, col[i]] будет тогда (N, 2 ) когда col[0] равно [1, 3]; для других i это может быть (N, 0) или (N, 1), (N, 3).

b[i, col[i]] равно (2,) (или (0,), (1, ), (3)). Там довольно очевидное несоответствие форм. Вы не можете поместить битовый (N, 2) массив в (2,) слот.

Почему вы пытаетесь создать такой массив? Сочетание None, чисел и массивов, имеющих такие формы, как (N, 1) и (N, 2)?


Я думаю, вам нужно добавить итерацию:

for j in col[i]:
    b[i, j] = mydata[:, j]

Это должно присвоить (N,) массив элементу b[i,j] b.

0 голосов
/ 23 марта 2020

Срез не работает должным образом для случаев, когда вы вставили более одного нулевого массива в строку из-за использования b[i, col[i]].

Просто рассмотрите вашу первую строку. Это дает вам row=[0], col =[[1,3]]. Это означает, что b[0,0] ссылается на массивы нулей для столбцов 1 и 3. Вы должны перебирать строки и столбцы с вложенным для l oop, как и раньше

for i in row:
    for j in col[i]:
        mydata = np.random.randn(N, len(a[0])).reshape(N, len(a[0]))
        b[i, j] = mydata[:, col[i]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...