传递给函数的numpy数组未更改

2024-06-16 12:45:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经试了很多办法来解决这个问题,但不幸的是没能解决它

我想把一个numpy数组传递给一个函数并在那里修改它

def GetDataFromDAQ(self, timestamp, msdata, signalname):
    tmptime, tmpdata = self.DAQ.return_data(signalname)
    timestamp= np.append(timestamp, tmptime)
    msdata = np.append(msdata, tmpdata)

这就是函数的调用

self.ActiveMSData = MeasurementData()
self.GetDataFromDAQ(self.ActiveMSData.RawData["timestamps"], self.ActiveMSData.RawData["data"], "frequency")

这是课堂的一部分

class MeasurementData():
def __init__(self):
    self.RawData = {}
    self.RawData["timestamps"] = np.empty(0)
    self.RawData["data"] = np.empty(0) 

我用VS代码对其进行了调试,发现函数中的数组timestamp和msdata已填充,但我传递的Measurementclass的成员根本没有更改
我错过了什么
提前感谢您的帮助
拉斐尔


Tags: 函数selfdatadefnp数组timestampappend
1条回答
网友
1楼 · 发布于 2024-06-16 12:45:28

函数中的赋值使函数范围内的变量名成为变量

如果GetDataFromDAQ是同一类/实例的方法/函数,则必须将新数组分配给实例属性

def GetDataFromDAQ(self, timestamp, msdata, signalname):
    tmptime, tmpdata = self.DAQ.return_data(signalname)
    self.RawData["timestamps"] = np.append(timestamp, tmptime)
    self.RawData["data"] = np.append(msdata, tmpdata)

如果希望函数不那么具体,则必须返回新数据

def GetDataFromDAQ(self, timestamp, msdata, signalname):
    tmptime, tmpdata = self.DAQ.return_data(signalname)
    t = np.append(timestamp, tmptime)
    d = np.append(msdata, tmpdata)
    return t,d

t = self.ActiveMSData.RawData["timestamps"]
d = self.ActiveMSData.RawData["data"]
t,d = self.GetDataFromDAQ(t,d,"frequency")
self.ActiveMSData.RawData["timestamps"],self.ActiveMSData.RawData["data"] = t,d

原始尝试的一个复杂之处是,您正在使用append创建一个全新的对象,而不是修改现有对象。如果您真的想尝试使函数通用化,您可以预测时间序列数据可能变成的最大大小,并数组初始化为该大小,并在数组中填充一个值,该值允许您确定插入下一系列数据的位置。然后在函数中,您可以分配给数组的一个片段,而无需创建新对象。像这样的

import numpy as np
rawdata = {'timestamps':np.full(10,np.nan),
           'data':np.full(10,np.nan)}

def f(t,d):
    nextt = np.argmax(np.isnan(t))
    nextd = np.argmax(np.isnan(d))
    newdata = [1,2,3]
    newtimestamps = [8,7,6]
    endt = nextt + len(newtimestamps)
    endd = nextd + len(newdata)
    t[nextt:endt] = newtimestamps
    d[nextd:endd] = newdata
    return None
    
##print(rawdata)
t = rawdata['timestamps']
d = rawdata['data']
f(t,d)
f(t,d)
print(rawdata)

从文档中教程的9.2. Python Scopes and Namespaces开始-

A special quirk of Python is that – if no global or nonlocal statement is in effect – assignments to names always go into the innermost scope. Assignments do not copy data — they just bind names to objects. The same is true for deletions: the statement del x removes the binding of x from the namespace referenced by the local scope. In fact, all operations that introduce new names use the local scope: in particular, import statements and function definitions bind the module or function name in the local scope.

上一节。9.1. 关于名称和对象的一个词,与文档语言参考部分中的4.2. Naming and binding一起值得一读


Numpy确实有一些操作,如果为它们的out参数指定了相同的名称,则这些操作可以就地修改,例如numpy.multiply-这些操作将按照您的预期工作。这里是一个玩具的例子

import numpy as np
rawdata = {'timestamps':np.ones(4),
           'data':np.ones(4) * 2}

def f(a,b):
    np.multiply(a, 5, out=a)
    np.subtract(b, 3, out=b)
    
print(rawdata)
a = rawdata['timestamps']
b = rawdata['data']
f(a,b)
print(rawdata)

相关问题 更多 >