5

I have an array of a size 2 x 2 and I want to change the size to 3 x 4.

A = [[1 2 ],[2 3]]
A_new = [[1 2 0 0],[2 3 0 0],[0 0 0 0]]

I tried 3 shape but it didn't and append can only append row, not column. I don't want to iterate through each row to add the column.

Is there any vectorized way to do this like that of in MATLAB: A(:,3:4) = 0; and A(3,:) = 0; this converted the A from 2 x 2 to 3 x 4. I was thinking is there a similar way in python?

3
  • You could do this type of thing with numpy, but not in pure python. If you're familiar with Matlab and want to use Python, you should definitely check out numpy. Commented May 14, 2015 at 4:18
  • @tom10, au contraire, see Shuai Liu's answer. Commented May 14, 2015 at 13:59
  • @try-catch-finally: OP says 1) "I don't want to iterate through each row..."; and 2) "Is there a way to vectorize..". The answer you refer to does not address either of these main points of the question. Eg, in their answer they say "[map] will iterate each item" Commented May 14, 2015 at 21:34

3 Answers 3

6

In Python, if the input is a numpy array, you can use np.lib.pad to pad zeros around it -

import numpy as np

A = np.array([[1, 2 ],[2, 3]])   # Input
A_new = np.lib.pad(A, ((0,1),(0,2)), 'constant', constant_values=(0)) # Output

Sample run -

In [7]: A  # Input: A numpy array
Out[7]: 
array([[1, 2],
       [2, 3]])

In [8]: np.lib.pad(A, ((0,1),(0,2)), 'constant', constant_values=(0))
Out[8]: 
array([[1, 2, 0, 0],
       [2, 3, 0, 0],
       [0, 0, 0, 0]])  # Zero padded numpy array

If you don't want to do the math of how many zeros to pad, you can let the code do it for you given the output array size -

In [29]: A
Out[29]: 
array([[1, 2],
       [2, 3]])

In [30]: new_shape = (3,4)

In [31]: shape_diff = np.array(new_shape) - np.array(A.shape)

In [32]: np.lib.pad(A, ((0,shape_diff[0]),(0,shape_diff[1])), 
                              'constant', constant_values=(0))
Out[32]: 
array([[1, 2, 0, 0],
       [2, 3, 0, 0],
       [0, 0, 0, 0]])

Or, you can start off with a zero initialized output array and then put back those input elements from A -

In [38]: A
Out[38]: 
array([[1, 2],
       [2, 3]])

In [39]: A_new = np.zeros(new_shape,dtype = A.dtype)

In [40]: A_new[0:A.shape[0],0:A.shape[1]] = A

In [41]: A_new
Out[41]: 
array([[1, 2, 0, 0],
       [2, 3, 0, 0],
       [0, 0, 0, 0]])

In MATLAB, you can use padarray -

A_new  = padarray(A,[1 2],'post')

Sample run -

>> A
A =
     1     2
     2     3
>> A_new = padarray(A,[1 2],'post')
A_new =
     1     2     0     0
     2     3     0     0
     0     0     0     0
Sign up to request clarification or add additional context in comments.

Comments

5

Pure Python way achieve this:

row = 3
column = 4
A = [[1, 2],[2, 3]]

A_new = map(lambda x: x + ([0] * (column - len(x))), A + ([[0] * column] * (row - len(A))))

then A_new is [[1, 2, 0, 0], [2, 3, 0, 0], [0, 0, 0, 0]].

Good to know:

  • [x] * n will repeat x n-times
  • Lists can be concatenated using the + operator

Explanation:

  • map(function, list) will iterate each item in list pass it to function and replace that item with the return value
  • A + ([[0] * column] * (row - len(A))): A is being extended with the remaining "zeroed" lists
    • repeat the item in [0] by the column count
    • repeat that array by the remaining row count
  • ([0] * (column - len(x))): for each row item (x) add an list with the remaining count of columns using

Comments

2

Q: Is there a vectorised way to ...

A: Yes, there is

A = np.ones(  (2,2) )                 # numpy create/assign 1-s
B = np.zeros( (4,5) )                 # numpy create/assign 0-s "padding" mat

B[:A.shape[0],:A.shape[1]] += A[:,:]  # numpy vectorised .ADD at a cost of ~270 us
B[:A.shape[0],:A.shape[1]]  = A[:,:]  # numpy vectorised .STO at a cost of ~180 us
B[:A.shape[0],:A.shape[1]]  = A       # numpy high-level .STO at a cost of ~450 us
B
Out[4]: 
array([[ 1.,  1.,  0.,  0.,  0.],
       [ 1.,  1.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.]])

Q: Is it resources efficient to "extend" the A´s data-structure in a smart way "behind the curtain"?

A: No, fortunately not much. Try bigger, big or huge sizes to feel the resources-allocation/processing costs...

Numpy has genuine data-structure "behind-the-curtain" that allows lot of smart tricks alike strided (re-)mapping, view-based operations, fast vectorised/broadcast operations, however, changing the memory-layout "accross the strided smart-mapping" is rather expensive. Numpy array model

For this reason numpy has added since 1.7.0 an in-built layout/mapper-modifier .lib.pad() that is well-aware & optimised so as to handle the "behind-the-curtain" structures both smart & fast.

B = np.lib.pad( A, 
                ( ( 0, 3 ), ( 0, 2) ),
                'constant',
                 constant_values = ( 0,  0 )
              )                                    # .pad() at a cost of ~ 270 us

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.