【问题标题】:How to replace one dimension of an n-dimensional array with another?如何用另一维替换n维数组的一维?
【发布时间】:2021-01-06 19:02:36
【问题描述】:

我有一个形状为 (4, 30, 13, 7000) 的 numpy 数组。这是实验数据。前三个维度代表实验条件。最后一个维度表示前三个维度的每个组合的 7000 毫秒。所以数组中有1560个7000ms的列表。

我已经构建了一个滑动窗口平均函数,我在每 7000 毫秒列表上执行一次:

def windowed_mean(4D_list)

    for trial in 4D_list:
        for neuron in trial:
            for timebin in neuron:
                chunk = timebin #chunk equals every 7000ms timespan. 
                window_size = 250 #ms
                i = 0
                while i < len(chunk) - window_size + 1: #sliding window average
                    window = chunk[i : i + window_size] #generates window
                    window_average = sum(window) / window_size #takes window average
                    moving_average.append(window_average) #appends window average to #moving_average list 
                    i += 25 #step size
    
                stored_averages.append(window_average)
                moving_average.clear()

    
    print(len(stored_averages)) #this list contains the stored windowed averages in order

我的问题是,如何将原始数组的第四维(时间)替换为存储在stored_averages 中的新窗口均值? 理想情况下,我希望得到一个新的形状数组 4, 30, 13, 271, 271,因为这是我每 7000 毫秒试用获得的窗口数。

【问题讨论】:

  • 请发布 MCVE。现在有一堆未定义的名字
  • 271、271从哪里来?你的卷积不是二维的吗?
  • 另外,你应该从你的函数中返回东西而不是打印它。否则你不能在其他任何地方使用它。

标签: python arrays numpy


【解决方案1】:

如果您想要移动平均线,请查看scipy.ndimage.convolve1d。滑动窗口只是与适当宽度和高度的框函数卷积。

你正在寻找类似的东西

def windowed_mean(arr, n, axis=-1):
    box = np.full(n, 1.0 / n)
    return ndimage.convolve1d(arr, box, axis)

这将返回一个与原始大小相同的数组。您可能想要一些不包含部分卷积元素的东西,因此您可以从左侧修剪(n - 1) // 2,从右侧修剪n // 2。使用这样的整数除法可确保修剪对于偶数和奇数窗口都是正确的:

    return  ndimage.convolve1d(arr, box, axis)[..., (n - 1) // 2:-(n // 2)]

您可以使用像 np.convolve 这样的一维卷积器进行相同的卷积。这将要求您的数据进行排列,以便您正在卷积的维度是连续的。这里很可能就是这种情况,因为 numpy 默认使用 C 顺序:

def windowed_mean(arr, n):
    box = np.full(n, 1.0 / n)
    conv = np.convolve(arr.ravel(), box)
    return conv[n - 1:].reshape(arr.shape)[..., :1 - n]

要对非最后一个维度进行操作,您必须将感兴趣的轴移动到最后。请记住,ravel 在这种情况下会复制数据:

def windowed_mean(arr, n, axis=-1):
    box = np.full(n, 1.0 / n)
    a = np.moveaxis(arr, axis, -1).ravel()
    conv = np.convolve(a, box)
    conv = conv[n - 1:].reshape(arr.shape)[..., :1 - n]
    return np.moveaxis(conv, -1, axis)

【讨论】:

    猜你喜欢
    • 2017-05-11
    • 1970-01-01
    • 2021-11-24
    • 1970-01-01
    • 2020-05-15
    • 2021-04-04
    • 2013-11-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多