简体   繁体   中英

adding arrays of different dimension in all cases python

x = np.array([[1],[1],[3]])
y = np.array([[1],[2]])
x+y

I have a few arrays I want to add together, they are structured like the above example. I want to add these arrays together, and where the dimension does not match up I want 0 added to that value. ie the result should be

array([[2],
       [3],
       [3]])

I do not know which of "x" or "y" will have higher dimension. Is there a nice way to deal with this? I've tried resizing the arrays to the maximum of the dimension between the two but no luck

Another possible solution, which usesnumpy.pad :

max_shape = np.maximum(x.shape[0], y.shape[0])

x = np.pad(x, ((0, max_shape - x.shape[0]), (0, 0)), mode='constant')
y = np.pad(y, ((0, max_shape - y.shape[0]), (0, 0)), mode='constant')

x + y

Output:

array([[2],
       [3],
       [3]])

just create another array that's the size of the longer one, and fill it with zeros for the empty values of the short array, then sum it with the longer array.

import numpy as np

def sum_padded(x,y):
    if len(x) > len(y):
        new_arr = np.zeros_like(x)
        new_arr[:len(y)] = y
        return x + new_arr
    elif len(x) < len(y):
        new_arr = np.zeros_like(y)
        new_arr[:len(x)] = x
        return y + new_arr
    else:
        return x + y

x = np.array([[1],[1],[3]])
y = np.array([[1],[2]])

res = sum_padded(x,y)
print(res)
[[2]
 [3]
 [3]]

note that this is assuming they have a different first dimension, if there is a difference in more dimensions than the first then it will get slightly more complicated, as you'll have to create two new arrays with a shape that's the max of both for all dimensions.

Here a possible solution:

all_arrays = [x, y]
max_len = max([len(arr) for arr in all_arrays])
sum_arr = np.zeros(max_len)
for arr in all_arrays:
    add_these_zeros = max_len - len(arr)
    sum_arr = sum_arr + np.concatenate([arr.flatten(), np.zeros(add_these_zeros)])
    
print(np.reshape(sum_arr, (-1, 1))) # reshape 1D to 2D
  • First put all your arrays in all_arrays
  • Calculate the length of the longest array
  • Create an array with as many zeros as the maximum length calculated in the previous step.
  • Iterate over the arrays
  • Calculate how many zeros the specific array needs to fill the maximum array size.
  • Add the zeros to the given array, and sum it to sum_arr

OUTPUT:

array([[2.],
       [3.],
       [3.]])

Keeping track of the various dimensions seems like the sticking point. Here, I use ravel / slice / reshape to flexibly deal with that.

def make_uniform(x, y):
    large = x if x.shape > y.shape else y
    # We return x with large.shape, optionally appending zeros.
    n = np.product(large.shape)
    return (
        np.concatenate(x, np.zeros_like(large))
        .ravel()[:n]
        .reshape(large.shape)
    )

x, y = (make_uniform(x, y),
        make_uniform(y, x))
x + y

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM