在滚动窗口中对多个数据数组进行操作的Python
考虑以下代码:在滚动窗口中对多个数据数组进行操作的Python,python,arrays,numpy,Python,Arrays,Numpy,考虑以下代码: class MyClass(object): def __init__(self): self.data_a = np.array(range(100)) self.data_b = np.array(range(100,200)) self.data_c = np.array(range(200,300)) def _method_i_do_not_have_access_to(self, data, win
class MyClass(object):
def __init__(self):
self.data_a = np.array(range(100))
self.data_b = np.array(range(100,200))
self.data_c = np.array(range(200,300))
def _method_i_do_not_have_access_to(self, data, window, func):
output = np.empty(np.size(data))
for i in xrange(0, len(data)-window+1):
output[i] = func(data[i:i+window])
output[-window+1:] = np.nan
return output
def apply_a(self):
a = self.data_a
def _my_func(val):
return sum(val)
return self._method_i_do_not_have_access_to(a, 5, _my_func)
my_class = MyClass()
print my_class.apply_a()
\u method\u i\u not\u have\u access\u to
方法接受一个numpy数组、一个窗口参数和一个用户定义的函数句柄,并返回一个数组,该数组包含在输入数据数组时窗口
数据点上的函数句柄输出的值-一种通用滚动方法。我无权更改此方法
如您所见,\u method\u i\u not\u access\u to
将一个输入传递给函数句柄,该函数句柄是传递给\u method\u i\u not\u access\u to的数据数组。该函数句柄仅计算通过方法传递给它的一个数据数组上基于输出的窗口
数据点
我需要做的是允许\u my\u func
(传递给\u方法\u I\u没有访问权\u的函数句柄)
)除了通过\u方法传递给\u my\u func
的数组之外,操作数据b
和数据c
,在同一窗口
索引中没有访问权限<代码>数据b
和数据c
在MyClass类
中全局定义
我想到的唯一方法是在\u my_func
中包含对数据b
和数据c
的引用,如下所示:
def _my_func(val):
b = self.data_b
c = self.data_c
# do some calculations
return sum(val)
def _my_func(val):
b = self.data_b # somehow identify which slide we are at
c = self.data_c # somehow identify which slide we are at
# if _method_i_do_not_have_access_to is currently
# operating on indexes 45->50, then the sum of
# val, b, and c should be the sum of the values at
# index 45->50 at each
return sum(val) * sum(b) + sum(c)
但是,我需要在与val
相同的索引处对b
和c
进行切片(请记住val
是通过\u方法\u我没有访问权\u的数组的长度-窗口
切片)
例如,如果\u method\u i\u not\u access\u to
中的循环当前在输入数组的索引45->50
上运行,\u my\u func
必须在b
和c
上的相同索引上运行
最终结果如下:
def _my_func(val):
b = self.data_b
c = self.data_c
# do some calculations
return sum(val)
def _my_func(val):
b = self.data_b # somehow identify which slide we are at
c = self.data_c # somehow identify which slide we are at
# if _method_i_do_not_have_access_to is currently
# operating on indexes 45->50, then the sum of
# val, b, and c should be the sum of the values at
# index 45->50 at each
return sum(val) * sum(b) + sum(c)
有没有关于如何实现这一目标的想法?这里有一个技巧:
创建一个新类DataProxy
,该类具有\uuuu getitem\uuuu
方法,并代理三个数据数组(例如,在初始化时可以传递给它)。使func作用于
DataProxy实例而不是标准numpy数组,并将修改后的func和代理传递给不可访问的方法
这有意义吗?其思想是,数据
不受数组约束,只是可以下标。因此,您可以创建一个自定义的可下标类来代替数组
例如:
class DataProxy:
def __init__(self, *data):
self.data = list(zip(*data))
def __getitem__(self, item):
return self.data[item]
然后创建一个新的DataProxy,在这样做时传入任意多的数组,并使func接受对所述实例进行索引的结果。试试看 问题是_my_______________________________________?如果您在调用函数时提前知道索引,最简单的方法就是使用lambda:lambda val:self.\u my_func(self.a,self.b,index,val)
,其中_my_func显然已更改以适应附加参数
由于您不知道索引,因此必须在self.c周围编写一个包装器,该包装器可以记住上次访问的索引(或者更好的方法是捕获slice操作符),并将其存储在一个变量中供函数使用
编辑:举出一个小例子,不是特别好的编码风格,但应该给你一个想法:
class Foo():
def __init__(self, data1, data2):
self.data1 = data1
self.data2 = data2
self.key = 0
def getData(self):
return Foo.Wrapper(self, self.data2)
def getKey(self):
return self.key
class Wrapper():
def __init__(self, outer, data):
self.outer = outer
self.data = data
def __getitem__(self, key):
self.outer.key = key
return self.data[key]
if __name__ == '__main__':
data1 = [10, 20, 30, 40]
data2 = [100, 200, 300, 400]
foo = Foo(data1, data2)
wrapped_data2 = foo.getData()
print(wrapped_data2[2:4])
print(data1[foo.getKey()])
既然\u method\u i\u do\u not..
似乎只是将函数应用于数据,那么您能让数据精确地成为一个索引数组吗?然后func
将使用索引对数据a
、数据b
和数据c
进行窗口访问。可能会有更快的方法,但我认为这将在增加复杂性的情况下实现
换句话说,大致上是这样的,如果需要,在窗口中添加额外的处理:
def apply_a(self):
a = self.data_a
b = self.data_b
c = self.data_c
def _my_func(window):
return sum(a[window]) * sum(b[window]) + sum(c[window])
return self._method_i_do_not_have_access_to(window_indices, 5, _my_func)
可以将二维数组传递给_method_i_do_not_have_access_to()。len()和切片操作将使用它:
In [29]: a = np.arange(100)
In [30]: b = np.arange(100,200)
In [31]: c = np.arange(200,300)
In [32]: data = np.c_[a,b,c] # make your three one dimension array to one two dimension array.
In [35]: data[0:10] # slice operation works.
Out[35]:
array([[ 0, 100, 200],
[ 1, 101, 201],
[ 2, 102, 202],
[ 3, 103, 203],
[ 4, 104, 204],
[ 5, 105, 205],
[ 6, 106, 206],
[ 7, 107, 207],
[ 8, 108, 208],
[ 9, 109, 209]])
In [36]: len(data) # len() works.
Out[36]: 100
In [37]: data.shape
Out[37]: (100, 3)
因此,您可以按如下方式定义_my_func:
def _my_func(val):
s = np.sum(val, axis=0)
return s[0]*s[1] + s[2]
哈,这不是我读的前三遍:)你能举个例子吗?我明天会试试看。我想我会遇到和我在上面的评论中提到的相同的问题。这是一个很好的清晰的解决方案,但不幸的是,\u方法\u我没有\u访问权\u似乎只针对输入数组的最后一个维度进行计算。这就是为什么我得出结论,唯一的解决方案是将全局数组传递到my_func
并在其中切片+谢谢你的评论,我将在本周试一试。