首页 > 解决方案 > python中菱形数组的数据结构

问题描述

我有两个通过映射操作相互关联的数组。我称它们为 S(f k ,f q ) 和 Z(f ij )。参数都是采样频率。映射规则相当简单:

f i = 0.5 · (f k - f q )
α j = f k + f q

S 是多次 FFT 和复数乘法的结果,定义在矩形网格上。但是,Z 是在菱形网格上定义的,我不清楚如何最好地存储它。下图是对 4×4 数组的简单示例的操作进行可视化的尝试,但通常尺寸不相等并且要大得多(可能是 64×16384,但这是用户可选择的)。蓝点是 f i和 α j的结果值,文本描述了它们与 f k、 f q和离散索引的关系。 菱形阵列表示 Z 的菱形性质意味着在一个“行”中将有“列”位于相邻“行”的“列”之间。可以采用小数索引值!

请注意,使用 0 或 nan 填充任何给定行中不存在的元素有两个缺点 1)它扩大了可能已经是非常大的 2-D 数组的大小和 2)它并不真正代表真实Z 的性质(例如,数组大小不会真正正确)。

目前我正在使用以 α j的实际值为索引的字典来存储结果:

import numpy as np
from collections import defaultdict
nrows = 64
ncolumns = 16384
fk = np.fft.fftfreq(nrows)
fq = np.fft.fftfreq(ncolumns)
# using random numbers here to simplify the example
# in practice S is the result of several FFTs and complex multiplications
S = np.random.random(size=(nrows,ncolumns)) + 1j*np.random.random(size=(nrows,ncolumns))

ret = defaultdict(lambda: {"fi":[],"Z":[]})
for k in range(-nrows//2,nrows//2):
    for q in range(-ncolumns//2,ncolumns//2):
        fi = 0.5*fk[k] - fq[q]
        alphaj = fk[k] + fq[q]
        Z = S[k,q]
        ret[alphaj]["fi"].append(fi)
        ret[alphaj]["Z"].append(Z)

我仍然觉得这有点麻烦,想知道是否有人对更好的方法有建议?这里的“更好”将被定义为计算和内存效率更高和/或更容易使用 matplotlib 之类的东西进行交互和可视化。

注意:这与另一个关于如何摆脱那些讨厌的 for 循环的问题有关。由于这是关于存储结果,我认为创建两个单独的问题会更好。

标签: pythonarraysnumpydata-structures

解决方案


您仍然可以将其视为直接的二维数组。但是您可以将其表示为一个行数组,其中每一行都有不同数量的项目。例如,这是您的 4x4 作为 2D 数组:(0这里每个都是唯一的数据项)

xxx0xxx
xx0x0xx
x0x0x0x
0x0x0x0
x0x0x0x
xx0x0xx
xxx0xxx

它的稀疏表示将是:

[
  [0],
  [0,0],
  [0,0,0],
  [0,0,0,0],
  [0,0,0],
  [0,0],
  [0]
]

通过这种表示,您可以消除空白。从色温转换为行,从光谱频率转换为列(反之亦然)涉及一些数学运算,但这很容易处理。您知道界限,并且项目在每一行中均匀分布。所以翻译应该很容易。

除非我错过了什么。. .


推荐阅读