0

I have to multiply two numpy arrays of different sizes (a and b), but I need to discard the first element of b before resizing.

What I see is that, if I use the full b array the resizing has no issues (but the result is not what I need, since it contains the first element of b). If I attempt to slice the first element off before applying resize I get a

ValueError: cannot resize this array: it does not own its data

Why does this happen, and how can I get around this in the most efficient way possible?

import numpy as np

# Some data
a = np.random.uniform(0., 1., 17)

# Works
b = np.array([56, 7, 343, 89, 234])
b.resize(a.shape)
d = b * a    

# Does not
b = np.array([56, 7, 343, 89, 234])[1:]
b.resize(a.shape)
d = b * a
6
  • Make a copy there with .copy() : ...234])[1:].copy() ? Commented Sep 9, 2017 at 17:19
  • I had the idea that copy() was not particularly efficient? This little block will be processed millions of times, so I need to make it as fast as possible. Also, why does the array not contain its data anymore after slicing? Commented Sep 9, 2017 at 17:21
  • 3
    If you care about performance, initialize a zero array and assign sliced array into it. Commented Sep 9, 2017 at 17:23
  • 1
    Also, why does the array not contain its data anymore after slicing? -Its a view into b, it doesn't have its own data. So, the in-place operation needed by resize won't work. Commented Sep 9, 2017 at 17:23
  • Is a normally (or always) larger than b? So the the resized b is padded with 0s?, d in that case will also be padded. Commented Sep 9, 2017 at 17:42

2 Answers 2

1

Another option is to just do the multiplication for the terms that matter:

n = len(b)-1
d = np.zeros_like(a)
d[:n] = b[1:] * a[:n]

for:

In [628]: a.shape
Out[628]: (1000000,)
In [629]: b=np.arange(100)

this is 2x faster than (which time about the same)

b.resize(len(a)+1,); d = b[1:] * a
b1 = b[1:].copy(); b1.resize(len(a)); d = b1 * a

Relative timings can vary with the size of b and a. While resize can be done in place, it probably will require a new data buffer, especially if it pads with a lot of zeros.

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

1 Comment

Indeed, this answer is much faster for large arrays, and a bit slower for smaller ones. Since my actual arrays are on the smaller side I'll use the copy() method, but this answer is the fastest for large arrays. Thanks!
1

the other order? pad out b to one element longer b.resize((len(a)+1,))

then multiply d = b[1:] * a

b = np.array([56, 7, 343, 89, 234])
b.resize((len(a)+1,))
d = b[1:] * a

1 Comment

Do you have any idea if this approach is faster to the copy() method mentioned by Divakar?

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.