-2

I have these two arrays:

import numpy as np
a = np.array([0, 10, 20])
b = np.array([20, 30, 40, 50])  

I´d like to add both in the following way while avoiding slow Python for loops:

c = array([20, 30, 40, 50, 30, 40, 50, 60, 40, 50, 60, 70])

It means, for the first element of "a" add all the elements of b,then for the second element and so on.

I know it seems quite easy, but for huge arrays Python loops are too slow.

Thanks.

7
  • 2
    What's wrong with for loops? Commented Nov 1, 2015 at 23:19
  • 1
    what are your arrays? numpy, array.array ? Commented Nov 1, 2015 at 23:20
  • do for's in list comprehensions count? ;) Commented Nov 1, 2015 at 23:22
  • 1
    there is no such thing as 'array' in Python. You have tuples or lists or sets. Commented Nov 1, 2015 at 23:22
  • 1
    @FernandoBastosGarcía, you should really add that you have numpy arrays and you want to avoid slow python loops Commented Nov 1, 2015 at 23:34

4 Answers 4

2

Here you go:

In [17]: a = np.array([0, 10, 20])

In [18]: b = np.array([20, 30, 40, 50])  

In [19]: (a.reshape(-1, 1) + b).ravel()
Out[19]: array([20, 30, 40, 50, 30, 40, 50, 60, 40, 50, 60, 70])

Here are the details.

a.reshape(-1, 1) converts a to an array with shape (3, 1):

In [20]: a.reshape(-1, 1)
Out[20]: 
array([[ 0],
       [10],
       [20]])

When b is added to that, broadcasting applies, which in effect does an "outer sum" (i.e. adds all the pairwise combinations), forming an array with shape (3, 4):

In [21]: a.reshape(-1, 1) + b
Out[21]: 
array([[20, 30, 40, 50],
       [30, 40, 50, 60],
       [40, 50, 60, 70]])

The ravel() method flattens the result into a one-dimensional array:

In [22]: (a.reshape(-1, 1) + b).ravel()
Out[22]: array([20, 30, 40, 50, 30, 40, 50, 60, 40, 50, 60, 70])

See @HYRY's answer for an even more concise version.

Sign up to request clarification or add additional context in comments.

Comments

1

you can use outer method of ufunc:

np.add.outer(a, b).ravel()

Comments

0

One possible and only memory not time intensive solution is using np.repeat and np.resize to repeat and resize the arrays a and b to the size of the resulting shape first and then simply add those two arrays.

Code:

import numpy as np
a = np.array([0, 10, 20])
b = np.array([20, 30, 40, 50])

def extend_and_add(a, b):
    return np.repeat(a, len(b)) + np.resize(b, len(a)*len(b))

So extend_and_add(a, b) returns:

extend_and_add(a, b)
> array([20, 30, 40, 50, 30, 40, 50, 60, 40, 50, 60, 70])

Explanation:

Basically np.repeat(a, len(b)) repeats:

a
> array([ 0, 10, 20])

to

np.repeat(a, len(b))
> array([ 0,  0,  0,  0, 10, 10, 10, 10, 20, 20, 20, 20])

after this you need the second array resized with np.resize:

b
> array([20, 30, 40, 50])

is resized to:

np.resize(b, len(a)*len(b))
> array([20, 30, 40, 50, 20, 30, 40, 50, 20, 30, 40, 50])

Now we can simply add the arrays:

array([ 0,  0,  0,  0, 10, 10, 10, 10, 20, 20, 20, 20])
+
array([20, 30, 40, 50, 20, 30, 40, 50, 20, 30, 40, 50])

returns:

array([20, 30, 40, 50, 30, 40, 50, 60, 40, 50, 60, 70])

Comments

-2

First you need to specify the array type, if you use a constructor like that. For instance for integers, use that:

a = array("i",[0, 10, 20])       # signed int type
b = array("i",[20, 30, 40, 50]) 

Them you might want to use while loops with counters, it is more complex than for, but avoids the for loop.

from array import array

a = array("i",[0, 10, 20])  # signed int

b = array("i",[20, 30, 40, 50]) 

c = array("i",[])

count1 = 0

while count1 < len(a):
   count2 = 0
   while count2 < len(b):
       c.append(a[count1]+b[count2])
       count2 += 1
   count1 += 1

print(c)

1 Comment

The OP is already using numpy; no need to switch to the other Python array module.

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.