Basj
Basj

Reputation: 46401

Insert a numpy array into another without having to worry about length

When doing:

import numpy 
A = numpy.array([1,2,3,4,5,6,7,8,9,10])
B = numpy.array([1,2,3,4,5,6])     

A[7:7+len(B)] = B                           # A[7:7+len(B)] has in fact length 3 !

we get this typical error:

ValueError: could not broadcast input array from shape (6) into shape (3)

This is 100% normal because A[7:7+len(B)] has length 3, and not a length = len(B) = 6, and thus, cannot receive the content of B !

How to prevent this to happen and have easily the content of B copied into A, starting at A[7]:

A[7:???] = B[???]     
# i would like [1 2 3 4 5 6 7 1 2 3]

This could be called "auto-broadcasting", i.e. we don't have to worry about length of arrays.


Edit: another example if len(A) = 20:

A = numpy.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20])
B = numpy.array([1,2,3,4,5,6])     

A[7:7+len(B)] = B
A # [ 1  2  3  4  5  6  7  1  2  3  4  5  6 14 15 16 17 18 19 20]

Upvotes: 3

Views: 377

Answers (3)

yashastew
yashastew

Reputation: 28

Just tell it when to stop using len(A).

A[7:7+len(B)] = B[:len(A)-7]

Example:

import numpy 
B = numpy.array([1,2,3,4,5,6])     

A = numpy.array([1,2,3,4,5,6,7,8,9,10])
A[7:7+len(B)] = B[:len(A)-7]
print A   # [1 2 3 4 5 6 7 1 2 3]

A = numpy.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20])
A[7:7+len(B)] = B[:len(A)-7]
print A   # [ 1  2  3  4  5  6  7  1  2  3  4  5  6 14 15 16 17 18 19 20]

Upvotes: 1

hpaulj
hpaulj

Reputation: 231355

Same question, but in 2d

Numpy - Overlap 2 matrices at a particular position

There I try to make the case that it is better that you take responsibility for determining which part of B should be copied:

A[7:] = B[:3]
A[7:] = B[-3:]
A[7:] = B[3:6]

np.put will do this sort of clipping for you, but you have to give it an index list, not a slice:

np.put(x, range(7,len(x)), B)

which isn't much better than x[7:]=y[:len(x)-7].

The doc for put tells me there is also a putmask, place, and copyto functions. And the counterpart to put is take.

An interesting thing is that while these other functions give more power than indexing, with modes like clip and repeat, I don't see them being used much. I think that's because it is easier to write a function that handles your special case, than it is to remember/lookup general functions with lots of options.

Upvotes: 0

user1269942
user1269942

Reputation: 3852

import numpy 
A = numpy.array([1,2,3,4,5,6,7,8,9,10])
B = numpy.array([1,2,3,4,5,6])     

numpy.hstack((A[0:7],B))[0:len(A)]

on second thought this fails the case where B fits inside A. soo....

import numpy 
A = numpy.array([1,2,3,4,5,6,7,8,9,10])
B = numpy.array([1,2,3,4,5,6])     

if 7 + len(B) > len(A):
    A = numpy.hstack((A[0:7],B))[0:len(A)]
else:
    A[7:7+len(B)] = B

but, this sort of defeats the purpose of the question! I'm sure you prefer a one-liner!

Upvotes: 1

Related Questions