Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在滚动窗口中对多个数据数组进行操作的Python_Python_Arrays_Numpy - Fatal编程技术网

在滚动窗口中对多个数据数组进行操作的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
并在其中切片+谢谢你的评论,我将在本周试一试。