2

In python 2.7.1 with numpy 1.5.1:

import numpy as np

B = np.matrix([[-float('inf'), 0], [0., 1]])
print B
Bm = B[1:, :]
Bm[:, 1] = float('inf')
print B

returns

[[-inf   0.]
 [  0.   1.]]
[[-inf   0.]
 [  0.  inf]]

which is quite unexpected because I thought Bm was a copy (as in this question).

Any help figuring this out will be appreciated.

Community
  • 1
  • 1
Mermoz
  • 14,898
  • 17
  • 60
  • 85
  • 1
    Note that `-float('inf')` is more directly `float('-inf')`, which has the benefit of not requiring a calculation (taking the opposite of a number). – Eric O. Lebigot Jun 12 '12 at 15:11
  • Also note that the point in `0.` in the matrix creation is not needed either: the presence of `float('inf')` guarantees that the matrix will be at least of floating type. – Eric O. Lebigot Jun 12 '12 at 15:12

3 Answers3

5

Basic slicing in numpy returns a view, as opposed to slicing Python lists, which copies them.

However, slicing will always copy data if using advanced slicing, just like concatenating or appending numpy arrays.

Compare

a = np.arange(16).reshape((4,4))
a_view = a[::2, ::3]  # basic slicing
a_copy = a[[0, 2], :]  # advanced
jorgeca
  • 5,482
  • 3
  • 24
  • 36
2

In my question, it was np.append that was making the copy. Slicing will not copy the array/matrix.

You can make Bm a copy with

Bm = B[1:, :].copy()
Fred Foo
  • 355,277
  • 75
  • 744
  • 836
0

This is interesting as from jorgeca's example:

a = np.arange(16).reshape((4,4))
a_view = a[::2, ::3]  # basic slicing
a_copy = a[[0, 2], :]  # advanced

My additional comment might be off-topic, but it is surprising that both of the following

a[::2, ::3]+= 1  # basic slicing
a[[0, 2], :]+= 1 # advanced

would make changes on a.

zhh210
  • 388
  • 4
  • 12