求k窗口上n个元素平均值的方法Pandas系列?(不是滚动平均值)

2024-09-25 00:26:27 发布

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

这里的动机是取一个时间序列,得到整个子时段(天、周)的平均活动量。在

可以改变数组的形状并取y轴上的平均值来实现这一点,类似于这个答案(但是使用轴=2):

Averaging over every n elements of a numpy array

但是我在找一个可以处理N%k长度数组的东西!=0,并且不能通过整形和用1或0填充来解决问题(例如numpy.调整大小),即仅取现有数据的平均值。在

例如,从长度N=10的序列[2,2,3,2,2,3,2,2,3,6]开始,该序列不能被k=3整除。我想要的是对具有不匹配维度的重塑数组的列取平均值:

In: [[2,2,3], [2,2,3], [2,2,3], [6]], k =3

Out: [3,2,3]

而不是:

In: [[2,2,3], [2,2,3], [2,2,3], [6,0,0]], k =3

Out: [3,1.5,2.25]

谢谢。在


Tags: 答案innumpy时间序列数组outover
3条回答

您可以通过填充、重塑形状和计算每行要划分多少元素来轻松实现这一点:

>>> import numpy as np
>>> a = np.array([2,2,3,2,2,3,2,2,3,6])
>>> k = 3

Pad数据

^{pr2}$

然后创建一个遮罩:

>>> c = a.size // k # 3
>>> d = (np.arange(k) + c * k) < a.size # [True, False, False]

d的第一部分将创建一个包含[9, 10, 11]的数组,并将其与a(10)的大小进行比较,生成所提到的布尔掩码。在

把它分开:

>>> b.sum(0) / (c + 1.0 * d)
array([ 3.,  2.,  3.])

上面的方法将第一列除以4(c + 1 * True),其余的除以3。这是矢量化的numpy,因此,它可以很好地扩展到大型阵列。在

所有的东西都可以写得更短,我只是展示所有的步骤,让它更清楚。在

通过解包链接将列表In展平。创建一个按列排列展开列表lst的新列表,然后使用map函数计算每列的平均值:

from itertools import chain

In = [[2, 2, 3], [2, 2, 3], [2, 2, 3], [6]]

lst = chain(*In)
k = 3

In_by_cols = [lst[i::k] for i in range(k)]
# [[2, 2, 2, 6], [2, 2, 2], [3, 3, 3]]

Out  = map(lambda x: sum(x)/ float(len(x)), In_by_cols)
# [3.0, 2.0, 3.0]

对每个子列表的长度使用float将在python2.x上提供更精确的结果,因为它不会进行整数截断。在

您可以使用一个屏蔽数组来填充在求平均值时忽略的特殊值,而不是求和。在

k = 3

# how long the array needs to be to be divisible by 3
padded_len = (len(in_arr) + (k - 1)) // k * k

# create a np.ma.MaskedArray with padded entries masked
padded = np.ma.empty(padded_len)
padded[:len(in_arr)] = in_arr
padded[len(in_arr):] = np.ma.masked

# now we can treat it an array divisible by k:
mean = padded.reshape((-1, k)).mean(axis=0)

# if you need to remove the masked-ness
assert not np.ma.is_masked(mean), "in_arr was too short to calculate all means"
mean = mean.data

相关问题 更多 >