Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.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 1d N阵列上切片的平均值:如何使其更具NumPy thonic?_Python_Arrays_Numpy - Fatal编程技术网

Python 1d N阵列上切片的平均值:如何使其更具NumPy thonic?

Python 1d N阵列上切片的平均值:如何使其更具NumPy thonic?,python,arrays,numpy,Python,Arrays,Numpy,作为我正在运行的一些模拟的一部分,我最终需要对一些非常长的(实数)序列执行以下操作。要点如下: 给定一个长的一维NumPy数组,对于数组中的每个位置,我想对该位置前后的值求平均值,取平均值之间的差值,并将这些差值加载到与原始数组相同维度的另一个nparray中 这是我的尝试。它工作得非常好,只是随着序列变长,速度会变得非常慢 将numpy导入为np def测试顺序(npseq): n=npseq.形状[0] 定义f(i): pre=np.和(npseq[:i])/i post=np.和(npse

作为我正在运行的一些模拟的一部分,我最终需要对一些非常长的(实数)序列执行以下操作。要点如下:

给定一个长的一维NumPy数组,对于数组中的每个位置,我想对该位置前后的值求平均值,取平均值之间的差值,并将这些差值加载到与原始数组相同维度的另一个nparray中

这是我的尝试。它工作得非常好,只是随着序列变长,速度会变得非常慢

将numpy导入为np
def测试顺序(npseq):
n=npseq.形状[0]
定义f(i):
pre=np.和(npseq[:i])/i
post=np.和(npseq[(i+1):])/(n-i)
回邮
out=np.数组([f(i)表示范围(1,n)中的i)])
返回
看起来很简单。但是

In [26]: a = np.random.randint(0,100,100000)
In [27]: %timeit example.test_sequence(a)
1 loops, best of 3: 7.69 s per loop

In [17]: a = np.random.randint(0,100,400000)
In [18]: %timeit example.test_sequence(a)
1 loops, best of 3: 1min 50s per loop
我知道可能有一种聪明的方法可以将其矢量化,但我对NumPy缺乏经验。谁能给我指出正确的方向吗


编辑:我最初写的是“总和”而不是“平均值”。我的意思是“平均值”。我的错。我知道这里可能有一个一个接一个的错误——我现在不担心。实际的问题比我在这里介绍的版本稍微复杂一些,所以无论如何我都需要处理它。

这里有一种方法使用
np.cumcum()

np.cumsum()
将生成上一项的总和,
a[::-1])[:-1]
是下一项的总和。因此,如果要计算平均值,则下一个项目的长度将为
np.arange(a.size,1,-1)
,而上一个项目的长度将为
np.arange(1,a.size)
,因此您可以执行以下操作:

np.cumsum(a[::-1])[::-1]/np.arange(a.size + 1, 1, -1) - np.cumsum(a)/np.arange(1, a.size + 1)
演示:


作为替代方案,您也可以使用pandas中的(即将弃用的)
expansing\u mean
功能:

import pandas as pd
a = np.array([32, 69, 79, 34,  1, 77, 54, 42, 73, 75])
pd.expanding_mean(a)[:-2:] - pd.expanding_mean(a[::-1])[-3::-1]
这里的输出匹配(我认为)函数的固定版本,但如果出现off by one错误,您可以按照自己的意愿进行修复:

def test_sequence(npseq):                                                                                           
    n = npseq.shape[0]                                                                                   

    def f(i):                                                                                          
        pre = np.sum(npseq[:i])/i
        post = np.sum(npseq[(i+1):])/(n-i-1)
        return pre-post                                                                                

    out = np.array([f(i) for i in range(1,n-1)])                                                         

    return out

test_sequence(a)

array([-22.375     ,  -0.35714286,   6.33333333, -10.7       ,
       -18.        , -14.66666667, -24.57142857, -26.5       ])
新的替换版本应使用扩展和平均值:

pd.Series(a[:-2:]).expanding().mean() - pd.Series(a[::-1]).expanding().mean()[-3::-1].reset_index(drop = True)

0   -22.375000
1    -0.357143
2     6.333333
3   -10.700000
4   -18.000000
5   -14.666667
6   -24.571429
7   -26.500000
dtype: float64
还有一些时机:

a = np.random.randint(0,100,100000)
%timeit test_sequence(a)
%timeit pd.Series(a[:-2:]).expanding().mean() - pd.Series(a[::-1]).expanding().mean()[-3::-1].reset_index(drop = True)

1 loop, best of 3: 8.17 s per loop
10 loops, best of 3: 18.5 ms per loop

看起来可能会加快速度。您的代码与您的描述不匹配。看起来您试图用平均值而不是求和来做一些事情,但是如果
post
应该是平均值,那么它很可能是一个一个的错误。是的,使用np.mean作为平均值以避免一个错误。@user2357112:这是一个打字错误。我是说一般。道歉!而且我也不太担心一个错误造成的后果。我最感兴趣的是如何将这种操作矢量化。
pd.Series(a[:-2:]).expanding().mean() - pd.Series(a[::-1]).expanding().mean()[-3::-1].reset_index(drop = True)

0   -22.375000
1    -0.357143
2     6.333333
3   -10.700000
4   -18.000000
5   -14.666667
6   -24.571429
7   -26.500000
dtype: float64
a = np.random.randint(0,100,100000)
%timeit test_sequence(a)
%timeit pd.Series(a[:-2:]).expanding().mean() - pd.Series(a[::-1]).expanding().mean()[-3::-1].reset_index(drop = True)

1 loop, best of 3: 8.17 s per loop
10 loops, best of 3: 18.5 ms per loop