【问题标题】:Incorrect reshaping of 3d array3d 数组的不正确重塑
【发布时间】:2021-02-21 21:41:50
【问题描述】:

我正在对形状为 1536 x 16 x 48 的矩阵进行一些处理。以下是有关此尺寸的一些详细信息:

  • 1536:6 秒内收集数据
  • 16:收集器的数量(在我的例子中是电极)
  • 48:样本数

所以,从 16 个不同的收集器的角度来看,我有 1536 个值的 48 个样本(代表 6 秒的数据)。

我的目标是对这个矩阵进行一些处理,但首先需要进行一些转换。

  1. 由于 6 秒是一个大序列,我想将每个样本分成更小的序列,特别是 3 或 2 秒。例如,1 个 6 秒样本 (1536) 可以拆分为 2 个 3 秒样本 (768) 或 3 个 2 秒样本 (512)。这个转换后的矩阵的形状将从1536x16x48 变为768x16x96(3 秒)或512x16x144(2 秒)。

  2. 一旦我有了这个新矩阵,我想重塑它,这样我就可以为每个观察者获得一个 2d 矩阵,并且所有值都以列而不是行组织(例如,2 秒拆分:512x16x144 => 144x512x16)。

  3. 最后,我现在可以遍历第 3 维 (16),对每个 2d 矩阵进行一些计算(即快速傅立叶变换),然后将它们全部归约(求和)为一个,以获得最终的 144 x 512 矩阵(在 2 秒分割场景中)。

下面的代码是我用numpy 做的,但是当我绘制从这个方法生成的样本时,这对我来说显然是错误的。

def generate_fft_data(data,labels, n_seconds_split=3):
    x = 256 * n_seconds_split
    y = 16
    z = 48 * int(6/n_seconds_split)
    data = data.transpose(2,0,1).reshape(x,y,z).transpose(2,0,1)
    fft_data = []
    for electrode in range(data.shape[2]):
        y_t = fft(data[:,:,electrode])
        fft_data.append(np.abs(y_t))
    sum_of_ffts = np.add.reduce(fft_data) 
    return sum_of_ffts

如果需要,我可以提供更多详细信息。提前致谢。

【问题讨论】:

  • 这听起来像是 xarray 的一个很好的用例
  • 感谢您的建议,但现在对我来说最困难的部分是(信不信由你)重塑/分割部分。

标签: python arrays numpy matrix


【解决方案1】:

你可以试试这个:

def generate_fft_data(data,n_seconds_split=3):
    x_split = 6//n_seconds_split
    # split along 0 axis, stack pieces along the last axis and transpose
    arr = np.dstack(np.split(data, x_split)).transpose(2,0,1)
    fft_data = []
    for electrode in range(arr.shape[2]):
        y_t = fft(arr[:,:,electrode])
        fft_data.append(np.abs(y_t))
    sum_of_ffts = np.add.reduce(fft_data) 
    return sum_of_ffts

【讨论】:

  • 谢谢。只是备注:在您的情况下,n_seconds_split 不代表所需样本的长度,而是将拆分原始样本的除数(例如,n_seconds_split=3 表示大小为 6/3 = 2 的样本)
【解决方案2】:
In [88]: data = np.ones((1536,16,48))
In [89]:  x = 256 * 3
    ...:  y = 16
    ...:  z = 48 * int(6/3)
In [90]: x,y,z
Out[90]: (768, 16, 96)
In [91]: data.transpose(2,0,1).shape
Out[91]: (48, 1536, 16)
In [92]: data.transpose(2,0,1).reshape(x,y,z).shape
Out[92]: (768, 16, 96)

将 [91] 重塑为 [92] 没有意义。它之所以有效,是因为数字“加起来”,但分布混乱。

我认为您想先将 1536 维度拆分为 (2,768)(或等效的 3),然后将该 2 维度移动到末尾,然后将其与 48 重新组合。

细节可能会有所不同,但这里有一个这样的顺序:

data1 = data.reshape(2,768,16,48).transpose(1,2,0,3).reshape(768,16,96)

【讨论】:

    猜你喜欢
    • 2021-12-31
    • 2016-02-10
    • 2017-10-15
    • 2023-04-05
    • 2014-12-27
    • 2017-11-11
    • 2020-05-15
    • 2017-09-18
    • 2020-04-22
    相关资源
    最近更新 更多