0

...better to directly show the code. Here it is:

import numpy as np
a = np.zeros([3, 3])
a
array([[ 0., 0., 0.],
       [ 0., 0., 0.],
       [ 0., 0., 0.]])
b = np.random.random_integers(0, 100, size = (1, 3))
b
array([[ 10,  3,  8]])
c = np.random.random_integers(0, 100, size = (4, 3))
c
array([[ 22, 21, 14],
       [ 55, 64, 12],
       [ 33, 85, 98],
       [ 37, 44, 45]])
a = b  will change dimensions of a
a = c  will change dimensions of a

for a = b, I want:

array([[ 10.,  3.,  8.],
       [  0.,  0.,  0.],
       [  0.,  0.,  0.]])

and for a = c, I want:

array([[ 22, 21, 14],
       [ 55, 64, 12],
       [ 33, 85, 98]])

So I want to lock the shape of 'a' so that values being assigned to it get "cropped" if necessary. Of course without if statements.

user1850133
  • 2,833
  • 9
  • 29
  • 39

2 Answers2

1

You can do this easily by using Numpy slice notation. Here is a SO question with good answers explaining it clearly. Essentially, you need to ensure that the shape of the left hand array and the right had array match, and you can achieve this by slicing the corresponding arrays appropriately.

import numpy as np
a = np.zeros([3, 3])
b = np.array([[ 10,  3,  8]])
c = np.array([[ 22, 21, 14],
       [ 55, 64, 12],
       [ 33, 85, 98],
       [ 37, 44, 45]])

a[0] = b
print a
a = c[0:3]
print a

Output:

[[ 10.   3.   8.]
 [  0.   0.   0.]
 [  0.   0.   0.]]
[[22 21 14]
 [55 64 12]
 [33 85 98]]

It seems you want to replace elements in the top left of a 2D array with elements from a second 2D array without worrying about the sizes of the arrays. Here is a method:

def replacer(orig, repl):
    new = np.copy(orig)
    w2, h1 = new.shape
    w1, h2 = repl.shape
    new[0:min(w1,w2), 0:min(h1,h2)] = repl[0:min(w1,w2), 0:min(h1,h2)]
    return new
print replacer(a,b)
print replacer(a,c)
Community
  • 1
  • 1
fraxel
  • 34,470
  • 11
  • 98
  • 102
1

The problem is that the equal operator is making a shallow copy of the array, and what you want is a deep copy of part of the array.

So for this, if you know that b only has one outer array, then you can do:

a[0] = b

And if know that a is a 3x3, then you could also do:

a = c[0:3]

Furthermore, if you want them to be actual deep copies, you'll want:

a[0] = b.copy()

and

a = c[0:3].copy()

To make them independent.

If you don't already know the lengths of the matrices, you can use the len() function to find out at runtime.

Leif Andersen
  • 21,580
  • 20
  • 67
  • 100
  • `The problem is that the equal operator is making a shallow copy of the array`. Actually the equal operator assigns a name to an object in Python, so `a=b` makes `a` and `b` refer to the same object. `a=b[:]` makes a shallow copy. – Mark Tolonen Jan 19 '13 at 19:48
  • Isn't that the definition of a shallow copy? I mean, wikipedia states that: `In this (shallow copy) process, B is attached to the same memory block as A.` That's why I said use the `copy()` function to make an actual deep copy. – Leif Andersen Jan 19 '13 at 19:57
  • Consider `a=[1,[2,3],4]; b=a`. `b[0]=5` will change both `a` and `b`, because they are the same object. A shallow copy is `b=a[:]`. `b[0]=5` will change b, but not a, but `b[1][0]=5` will change both. `b` is a shallow copy of `a` because it is a new list object, but the 2nd element is the same sublist. You can use the `id()` command to verify this. – Mark Tolonen Jan 19 '13 at 20:03
  • Remember that we're dealing with numpy arrays here, not lists. And (as far as I can tell) the only way to make a deep copy of the list is to use the `copy()` function. (Although yes, you are correct that `[:]` would make a copy of a list). – Leif Andersen Jan 19 '13 at 20:08
  • Python assignment is Python assignment. I was just objecting to the terminology. There is no copying involved. There is a difference between `a=b` and `a=b[:]` even with numpy arrays. The first case `a` and `b` are the same object. In the second `a` and `b` are different objects. If those objects are numpy arrays, they in fact still point to the same memory block, but are different Python objects. That is a shallow copy...a new object with the same internal objects references. A deep copy is a new object with new internal object references as well. – Mark Tolonen Jan 19 '13 at 20:14