I was going to repeat the core of my linked answer, and say that transpose
is the most likely case where reshape
will produce a copy.
But then I thought of a case where the view
is produces a non-contiguous selection:
In [181]: x = np.arange(16).reshape(4,4)
In [182]: x1 = x[::2,::2]
In [183]: x
Out[183]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
In [184]: x1
Out[184]:
array([[ 0, 2],
[ 8, 10]])
In [185]: x1[0,0]=100
In [186]: x
Out[186]:
array([[100, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[ 12, 13, 14, 15]])
x1
, created with basic indexing, is a view
. But a reshape of it is a copy:
In [187]: x2 = x1.reshape(-1)
In [188]: x2
Out[188]: array([100, 2, 8, 10])
In [189]: x2[0] = 200
In [190]: x1
Out[190]:
array([[100, 2],
[ 8, 10]])
In [191]: x
Out[191]:
array([[100, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[ 12, 13, 14, 15]])
A simple test for a copy is to look at the ravel
. ravel
is a reshape
; if the ravel isn't the same as the originals, or a subset of it, it's a copy.
In [192]: x.ravel()
Out[192]:
array([100, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15])
In [193]: x1.ravel()
Out[193]: array([100, 2, 8, 10]) # x1 is a view, but a reshape is a copy
In [194]: xt = x.T
In [195]: xt
Out[195]:
array([[100, 4, 8, 12],
[ 1, 5, 9, 13],
[ 2, 6, 10, 14],
[ 3, 7, 11, 15]])
In [196]: xt.ravel() # xt is a view, but its reshape is a copy
Out[196]:
array([100, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3,
7, 11, 15])
selecting two rows is a view, and its reshape is one too:
In [197]: x[:2].ravel()
Out[197]: array([100, 1, 2, 3, 4, 5, 6, 7])
In [198]: x[:2].ravel()[0]=200
In [199]: x
Out[199]:
array([[200, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[ 12, 13, 14, 15]])
but not when selecting two columns:
In [200]: x[:,:2].ravel()
Out[200]: array([200, 1, 4, 5, 8, 9, 12, 13])
In [201]: x[:,:2].ravel()[0]=150
In [202]: x
Out[202]:
array([[200, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[ 12, 13, 14, 15]])
As for predicting a copy without actually doing it - I'd depend more on experience than some code (which I attempted in the linked answer). I have a good idea of how the data is layed out, or can easily test for it.
Keep in mind when this copy/no-copy is important. As I showed, the copy case keeps us from modifying the original array. Whether that's good or not depends on the situation. In other cases we don't really care. The performance cost of a copy isn't that great.