Это типичный способ построения массива из списков списков:
In [127]: alist = []
...: for i in range(3):
...: sublist = []
...: for j in range(4):
...: sublist.append(i*10+j)
...: alist.append(sublist)
...:
In [128]: alist
Out[128]: [[0, 1, 2, 3], [10, 11, 12, 13], [20, 21, 22, 23]]
In [129]: np.array(alist)
Out[129]:
array([[ 0, 1, 2, 3],
[10, 11, 12, 13],
[20, 21, 22, 23]])
Я пытался повторить подход добавления списка с concatenates
, но продолжал сталкиваться с ошибками вроде
ValueError: all the input arrays must have same number of dimensions
ValueError: all the input array dimensions except for the concatenation axis must match exactly
In [130]: arr = np.zeros((0,4), int)
...: for i in range(3):
...: arr1 = np.zeros((0),int)
...: for j in range(4):
...: arr1 = np.concatenate((arr1, np.array([i*10+j])))
...: arr = np.concatenate((arr, arr1), axis=0)
Я мог бы в конечном итоге получить правильные размеры, но это не стоит моего времени.
Самый быстрый, не итеративный подход - это что-то вроде:
In [133]: np.arange(4)+10*np.arange(3)[:,None]
Out[133]:
array([[ 0, 1, 2, 3],
[10, 11, 12, 13],
[20, 21, 22, 23]])
Если вы должны выполнить итерацию, этопроще создать пустой массив правильного размера и присвоить значения:
In [135]: arr = np.zeros((3,4),int)
...: for i in range(3):
...: for j in range(4):
...: arr[i,j] = 10*i+j
...: arr
Out[135]:
array([[ 0, 1, 2, 3],
[10, 11, 12, 13],
[20, 21, 22, 23]])
Этот последний подход имеет скорость, сравнимую с добавлением в список.
Очищено concatenate
версия.
arr
будет 2d, (n, 4), на каждом шаге.
arr1
равно 1d, (m,), на каждом шаге;его нужно расширить до 2d, чтобы объединить с arr
.
In [158]: arr = np.zeros((0,4), int)
...: for i in range(3):
...: arr1 = np.zeros((0,),int)
...: for j in range(4):
...: arr1 = np.concatenate((arr1, np.array([i*10+j])))
...: arr = np.concatenate((arr, arr1[None,:]), axis=0)
...:
In [159]: arr
Out[159]:
array([[ 0, 1, 2, 3],
[10, 11, 12, 13],
[20, 21, 22, 23]])
np.append
- это всего лишь concatenate
, что гарантирует, что входы по крайней мере 1d.Таким образом, мы можем использовать его во внутреннем цикле.np.vstack
гарантирует, что его входы 2d, поэтому мы можем использовать его во внешнем цикле.Они просто скрывают детали;они не меняют скорость.
In [161]: arr = np.zeros((0,4), int)
...: for i in range(3):
...: arr1 = np.zeros((0,),int)
...: for j in range(4):
...: arr1 = np.append(arr1, i*10+j)
...: arr = np.vstack((arr, arr1))