如何计算由索引数组定义的 window 大小不同的 NumPy 数组的移动平均值?
How to calculate moving average of NumPy array with varying window sizes defined by an array of indices?
根据一维数组中的范围对二维数组(轴=1)中的值进行平均的最pythonic方法是什么?
我正在尝试根据每 2 个纬度(我的 id 数组)对环境变量数组(我的二维数组)进行平均。我有一个从 -33.9 到 29.5 的纬度数组。我想平均每 2 度内的环境变量,从 -34 到 30。
每2度内的元素个数可能不同,例如:
arr = array([[5,3,4,5,6,4,2,4,5,8],
[4,5,8,5,2,3,6,4,1,7],
[8,3,5,8,5,2,5,9,9,4]])
idx = array([1,1,1,2,2,3,3,3,3,4])
然后我会根据 idx[0:3]
、idx[3:9]
、idx[9]
.
对 arr 中的值进行平均
我想得到以下结果:
arrAvg = array([4,4.2,8],
[6.3,3.5,7],
[5.3,6.3,4])
您可以使用 np.hsplit
函数。对于您的索引 0:3, 3:9, 9
示例,它是这样的:
np.hsplit(arr, [3, 9])
它给你一个数组列表:
[array([[5, 3, 4],
[4, 5, 8],
[8, 3, 5]]),
array([[5, 6, 4, 2, 4, 5],
[5, 2, 3, 6, 4, 1],
[8, 5, 2, 5, 9, 9]]),
array([[8],
[7],
[4]])]
然后你可以计算平均值如下:
m = [np.mean(a, axis=1) for a in np.hsplit(arr, [3, 9])]
并将其转换回数组:
np.vstack(m).T
已经在他的 post 中解释了如何计算具有指数列表的平均值。
我将提供获取这些索引的解决方案。
这是一个通用的方法:
from typing import Optional
import numpy as np
def get_split_indices(array: np.ndarray,
*,
window_size: int,
start_value: Optional[int] = None) -> np.ndarray:
"""
:param array: input array with consequent integer indices
:param window_size: specifies range of indices
which will be included in a separate window
:param start_value: from which the window will start
:return: array of indices marking the borders of the windows
"""
if start_value is None:
start_value = array[0]
diff = np.diff(array)
diff_indices = np.where(diff)[0] + 1
slice_ = slice(window_size - 1 - (array[0] - start_value) % window_size,
None,
window_size)
return diff_indices[slice_]
用法示例:
用你的示例数据检查它:
# indices: 3 9
idx = np.array([1,1,1, 2,2,3,3,3,3, 4])
你可以得到分隔不同 windows 的索引,如下所示:
get_split_indices(idx,
window_size=2,
start_value=0)
>>> array([3, 9])
使用此功能您还可以指定不同的 window 尺寸:
# indices: 7 11 17
idx = np.array([0,1,1,2,2,3,3, 4,5,6,7, 8,9,10,11,11,11, 12,13])
get_split_indices(idx,
window_size=4,
start_value=0)
>>> array([ 7, 11, 17])
和不同的起始值:
# indices: 1 7 10 13 18
idx = np.array([0, 1,1,2,2,3,3, 4,5,6, 7,8,9, 10,11,11,11,12, 13])
get_split_indices(idx,
window_size=3,
start_value=-2)
>>> array([ 1, 7, 10, 13, 18])
请注意,我默认将数组的第一个元素作为起始值。
根据一维数组中的范围对二维数组(轴=1)中的值进行平均的最pythonic方法是什么?
我正在尝试根据每 2 个纬度(我的 id 数组)对环境变量数组(我的二维数组)进行平均。我有一个从 -33.9 到 29.5 的纬度数组。我想平均每 2 度内的环境变量,从 -34 到 30。
每2度内的元素个数可能不同,例如:
arr = array([[5,3,4,5,6,4,2,4,5,8],
[4,5,8,5,2,3,6,4,1,7],
[8,3,5,8,5,2,5,9,9,4]])
idx = array([1,1,1,2,2,3,3,3,3,4])
然后我会根据 idx[0:3]
、idx[3:9]
、idx[9]
.
我想得到以下结果:
arrAvg = array([4,4.2,8],
[6.3,3.5,7],
[5.3,6.3,4])
您可以使用 np.hsplit
函数。对于您的索引 0:3, 3:9, 9
示例,它是这样的:
np.hsplit(arr, [3, 9])
它给你一个数组列表:
[array([[5, 3, 4],
[4, 5, 8],
[8, 3, 5]]),
array([[5, 6, 4, 2, 4, 5],
[5, 2, 3, 6, 4, 1],
[8, 5, 2, 5, 9, 9]]),
array([[8],
[7],
[4]])]
然后你可以计算平均值如下:
m = [np.mean(a, axis=1) for a in np.hsplit(arr, [3, 9])]
并将其转换回数组:
np.vstack(m).T
我将提供获取这些索引的解决方案。
这是一个通用的方法:
from typing import Optional
import numpy as np
def get_split_indices(array: np.ndarray,
*,
window_size: int,
start_value: Optional[int] = None) -> np.ndarray:
"""
:param array: input array with consequent integer indices
:param window_size: specifies range of indices
which will be included in a separate window
:param start_value: from which the window will start
:return: array of indices marking the borders of the windows
"""
if start_value is None:
start_value = array[0]
diff = np.diff(array)
diff_indices = np.where(diff)[0] + 1
slice_ = slice(window_size - 1 - (array[0] - start_value) % window_size,
None,
window_size)
return diff_indices[slice_]
用法示例:
用你的示例数据检查它:
# indices: 3 9
idx = np.array([1,1,1, 2,2,3,3,3,3, 4])
你可以得到分隔不同 windows 的索引,如下所示:
get_split_indices(idx,
window_size=2,
start_value=0)
>>> array([3, 9])
使用此功能您还可以指定不同的 window 尺寸:
# indices: 7 11 17
idx = np.array([0,1,1,2,2,3,3, 4,5,6,7, 8,9,10,11,11,11, 12,13])
get_split_indices(idx,
window_size=4,
start_value=0)
>>> array([ 7, 11, 17])
和不同的起始值:
# indices: 1 7 10 13 18
idx = np.array([0, 1,1,2,2,3,3, 4,5,6, 7,8,9, 10,11,11,11,12, 13])
get_split_indices(idx,
window_size=3,
start_value=-2)
>>> array([ 1, 7, 10, 13, 18])
请注意,我默认将数组的第一个元素作为起始值。