Python3、Numpy:将数据拆分成固定长度的块,并为每个块计算统计量

Python 3, Numpy: Split data into blocks of fixed length and calculate statistics for each block

快速解决方案

如果您只想将 numpy 数组或 python 列表拆分为固定长度的数组或列表,请执行以下操作:

l = 10 # the fixed length of output array
output = [input[l*i:l*(i+1)-1] for i in range(0, len(input) // l)]

如果输入不是可被 l 整除的整数,但您想在输出中包含最终(较短的)数组,请执行以下操作:

l = 10 # the fixed length of output array
output = [input[l*i:l*(i+1)-1] for i in range(0, (len(input) + l - 1) // l)]

完整问题

我正在尝试计算一些数据的一些统计数据。示例统计信息包括平均值、标准差、最小值和最大值。

数据被格式化为 python numpy 数组。这是一个简单的例子:

data_in = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
data_array = numpy.array(data_in)

此处示例的数组长度为 10,但在实践中,考虑输入数据的长度为 100 万个元素(但不是精确的整数),输出应统计大约 10k 的块元素。

我是这样尝试的。下面的示例仅针对均值统计显示。

mean_out = [numpy.mean(data_array[2*i:2*i+1]) for i in range(0, len(data_array) // 2)]

这似乎不是一个特别优雅的解决方案。这里的“块长”是2,在上面的表达式中出现了3处。

这可以用 bl 作为块长度以更通用的方式编写。

mean_out = [numpy.mean(data_array[bl*i:bl*(i+1)-1]) for i in range(0, len(data_array) // bl)]

除此之外,当输入数据长度不能被块长度整除时,上述方法不起作用。例如,将块长度更改为 3 会导致长度为 3 的输出。

3 * 3 = 9 起,计算中缺少最后一个元素。

这可以通过使用以下表达式“修复”:

mean_out = [numpy.mean(data_array[bl*i:bl*(i+1)-1]) for i in range(0, (len(data_array) + bl - 1) // bl)]

但同样,这不是特别优雅。

是否有内置的 python 或 numpy 函数通过将输入数组拆分为固定长度的块来计算这些统计数据?或者有没有更好的方法来进行我不知道的计算?

Numpy array_split 可以将数组拆分成块。要计算每个块的 mean,您可以使用 map

data_arrays = np.array_split(data_array, len(data_array) // 2)
print(data_arrays) # [array([1, 2]), array([3, 4]), array([5, 6]), array([7, 8]), array([ 9, 10])]
print(list(map(np.mean, data_arrays))) # [1.5, 3.5, 5.5, 7.5, 9.5]

data_arrays = np.array_split(data_array, len(data_array) // 3)
print(data_arrays) # [array([1, 2, 3, 4]), array([5, 6, 7]), array([ 8,  9, 10])]
print(list(map(np.mean, data_arrays))) # [2.5, 6.0, 9.0]

注意:要在iter对象中映射returns,转换得到相同格式的输出(numpy数组),需要以下内容:

numpy.fromiter(map(numpy.mean, data_array), dtype=numpy.float)

同样的事情可以通过转换为列表,然后转换为 numpy 数组来完成,如上所示。