切片表示法不会在内存中创建新副本

时间:2017-10-24 20:10:33

标签: python numpy scipy

我使用scipy和imread()将图像导入为RGB。假设我想分离出“R”组件并将其复制到内存中的新对象。以下代码有效:

import scipy as sp
import scipy.misc as misc
import matplotlib.pyplot as plt
%matplotlib inline 
pic = misc.imread("ARBITRARY IMAGE.png");

r = pic[:,:,0].copy()
r[0,0] = 0
print(r[0,0])
print(pic[0,0,0])

输出预期的:

0
255

但是我通过以下途径到达那里,我不知道他们为什么不工作:

r = pic[:,:,0]
r[0,0] = 0
print(r[0,0])
print(pic[0,0,0])

输出:

0
0

很公平,我从here获取了语法提示,它涉及使用像b = a[:]这样的切片而不是单个图层。怎么样:

r = pic[:]
r[0,0,0] = 0
print(r[0,0,0])
print(pic[0,0,0])

或添加额外的步骤:

r = pic[:]
r= r[:,:,0]
r[0,0] = 0
print(r[0,0])
print(pic[0,0,0])

仍然输出:

0
0

这是一个不是列表的数组,但是数组的this answer意味着这个语法应该没问题。基本上,当我在示例中使用切片表示法时,如何在内存中创建新对象?我假设我错过了其他的东西,我的谷歌搜索似乎告诉我语法应该工作。谢谢你的帮助!

1 个答案:

答案 0 :(得分:3)

other question you linked使用了错误的术语;它询问Python 列表,而你正在使用Numpy数组。切片列表确实会为您提供所选范围的副本,但会slicing an array gives you a view。您对视图所做的更改将反映在原始视图中。

使用Numpy数组时,您需要使用copy()来获取可以更改的单独副本,而不会影响原始数据。这是一个设计选择,因为Numpy数组通常非常大,你不会想要无意中复制它们。