Numpy: построение 3D-массива из одномерного массива

#arrays #numpy

#массивы #numpy

Вопрос:

Предположим, что задан одномерный массив A . Есть ли простой способ построить 3D-массив, B такой, чтобы B[i,j,k] = A[k] для всех i, j, k? Можно предположить, что форма B задана, и это B.shape[2] = A.shape[0] .

Комментарии:

1. Вы имеете в виду, что хотите разбить массив на плитки? docs.scipy.org/doc/numpy/reference/generated/numpy.tile.html

Ответ №1:

 >>> k = 4
>>> a = np.arange(k)
>>> j = 3
>>> i = 2
>>> np.tile(a,j*i).reshape((i,j,k))
array([[[0, 1, 2, 3],
        [0, 1, 2, 3],
        [0, 1, 2, 3]],

       [[0, 1, 2, 3],
        [0, 1, 2, 3],
        [0, 1, 2, 3]]]
  

Комментарии:

1. Вы можете заменить np.tile(np.tile(a,j),i).reshape((i,j,k)) на np.tile(a, i*j).reshape((i,j,k))

2. Я удалил свое np.tile(A,(i,j,1)) предложение, потому что у него была ужасная производительность для больших массивов. Знаете, почему np.tile(A,i*j).reshape(i,j,k) масштабируется намного лучше?

3. @MLW: Я набрал numpy.source(numpy.tile) и увидел, что это tile вызывает reshape и repeat для каждого элемента в reps кортеже. reshape возвращает копию, что означает перераспределение всей этой памяти каждый раз. Мне кажется плохо реализованным.

Ответ №2:

Еще один простой способ сделать это — простое назначение — трансляция автоматически выполнит правильные действия:

 i = 2
j = 3
k = 4
a = numpy.arange(k)
b = numpy.empty((i, j, k))
b[:] = a
print b
  

С принтами

 [[[ 0.  1.  2.  3.]
  [ 0.  1.  2.  3.]
  [ 0.  1.  2.  3.]]

 [[ 0.  1.  2.  3.]
  [ 0.  1.  2.  3.]
  [ 0.  1.  2.  3.]]]
  

Ответ №3:

 for k,v in enumerate(A): B[:,:,k] = v
  

Комментарии:

1. Разве это не очень неэффективно, поскольку включает медленный цикл for?

2. @celli Размер этого массива равен O (n) A , и ни один алгоритм не может сделать это лучше, потому что каждый элемент A должен быть проверен для выполнения вычисления. В других ответах предполагалось, что использование numppy.tile() является лучшим вариантом, чем прямое присвоение. Решение, которое я предлагаю, является ясным и pythonic, и я ожидаю, что NumPy эффективно обработает назначения (возможно, с tile() ), но нужно было бы измерить (время), чтобы знать.