2014-10-19 2 views
3

Я хочу иметь массив numpy двух других массивов (каждый из них имеет другую форму). Как я знаю, по этой причине нужно использовать: dtype = object в определении основного массива.numpy.array с элементами различной формы

Например, определим (в Python 2.7) наши массивы

 a0 = np.arange(2*2).reshape(2,2) 
    a1 = np.arange(3*3*2).reshape(3,3,2) 
    b = np.array([a0,a1], dtype = object) 

Это отлично работает: b[1] так же, как a1. Но если изменить размер в a0 от (2,2) до (3,3) происходит нечто странное:

 a0 = np.arange(3*3).reshape(3,3) 
    a1 = np.arange(3*3*2).reshape(3,3,2) 
    b = np.array([a0,a1], dtype = object) 

На этот раз b[1] и a1 не равны, они даже имеют разные формы. В чем причина этого странного поведения?

Возможно, для меня существует совершенно другое решение. Но я не хочу использовать списки или кортежи, потому что хочу разрешить добавление, например b + b. Понятно, что я могу написать свой собственный класс для этой цели, но есть ли более простой способ?

ответ

2

Если вы явно хотите массив объектов, вы можете создать пустой массив объектов типа первый и назначить ему:

x = empty(5, dtype=object) 
x[0] = zeros((3,3)) 
x[1] = zeros((3,2)) #does not merge axes. 
x[2] = eye(4) 
x[3] = ones((2,2))*2 
x[4] = arange(10).reshape((5,2)) 

>>> x+x 
array([array([[ 0., 0., 0.], 
    [ 0., 0., 0.], 
    [ 0., 0., 0.]]), 
    array([[ 0., 0.], 
    [ 0., 0.], 
    [ 0., 0.]]), 
    array([[ 2., 0., 0., 0.], 
    [ 0., 2., 0., 0.], 
    [ 0., 0., 2., 0.], 
    [ 0., 0., 0., 2.]]), 
    array([[ 4., 4.], 
    [ 4., 4.]]), 
    array([[ 0, 2], 
    [ 4, 6], 
    [ 8, 10], 
    [12, 14], 
    [16, 18]])], dtype=object) 

Вы должны заполнить все элементы, прежде чем выполнять арифметические операции, или расти элемент от нуля, используя np.append.

+0

В вашем примере невозможно выполнить арифметику для всего массива 'x'. Например, 'x + x' не будет работать. – cheyp

+1

Да, вы можете! Вам просто нужно заполнить все элементы 0..4, как я сказал (но только дал пример для первых двух). – mdurant

3

Я не думаю, что это странное поведение, так вы используете numpy, это странно для меня.

numpy сгущает размер как можно больше. Это поведение по умолчанию, и это то, что ожидается при работе с массивами. В первом примере все размеры a0 и a1 различны. numpy вынужден использовать только первое измерение. Итак, если мы посмотрим на b.shape в первом примере, мы увидим (2,).

Во втором примере a0 и a1 имеют такой же размерный размер вплоть до последнего измерения. Таким образом, numpy объединяет эти уровни. Если вы посмотрите на b.shape здесь, вы увидите (2,3,3), так как второе и третье измерение имеют одинаковый размер.

Смежные вопросы