如何使用两个视图修改NumPy.recarray
我刚开始学习Python和Numpy,遇到了一个问题,就是在使用掩码视图时,无法修改numpy.recarray。我从一个文件中读取了recarray,然后创建了两个掩码视图,接着在一个循环中尝试修改这些值。下面是一个示例代码。
import numpy as np
import matplotlib.mlab as mlab
dat = mlab.csv2rec(args[0], delimiter=' ')
m_Obsr = dat.is_observed == 1
m_ZeroScale = dat[m_Obsr].scale_mean < 0.01
for d in dat[m_Obsr][m_ZeroScale]:
d.scale_mean = 1.0
但是当我打印结果时
newFile = args[0] + ".no-zero-scale"
mlab.rec2csv(dat[m_Obsr][m_ZeroScale], newFile, delimiter=' ')
文件中的所有scale_means仍然是零。
我一定是做错了什么。有没有正确的方法来修改视图中的值?是不是因为我一个接一个地应用了两个视图?
谢谢。
1 个回答
4
我觉得你对“遮罩视图”这个词有些误解,建议你再看看这本书(现在可以免费下载),这样能帮助你更好地理解。
我引用一下第3.4.2节的内容:
当选择对象(obj)是一个非元组的序列对象、一个ndarray(数据类型为整数或布尔值),或者是一个包含至少一个序列对象或ndarray(数据类型为整数或布尔值)的元组时,就会触发高级选择。高级索引有两种类型:整数和布尔。高级选择总是返回数据的一个副本(与基本切片返回视图不同)。
你在这里做的其实是布尔类型的高级选择,所以你得到的是一个副本,而不是直接绑定到原始数据上——你在这个副本上进行修改,然后就让它消失了,最后再从原始数据中写一个新的副本。
一旦你理解了这个问题,解决方案应该很简单:只需复制一次,在那个副本上进行修改,然后写回那个副本。也就是说:
dat = mlab.csv2rec(args[0], delimiter=' ')
m_Obsr = dat.is_observed == 1
m_ZeroScale = dat[m_Obsr].scale_mean < 0.01
the_copy = dat[m_Obsr][m_ZeroScale]
for d in the_copy:
d.scale_mean = 1.0
newFile = args[0] + ".no-zero-scale"
mlab.rec2csv(the_copy, newFile, delimiter=' ')