Python中菱形数组的数据结构 [英] Data structure for a diamond-shaped array in python

查看:55
本文介绍了Python中菱形数组的数据结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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的菱形性质意味着在一个行中将存在一个列,它们位于的列之间相邻的行。另一种思考方式是f i 可以采用分数索引值!



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



当前我正在使用将α j 的实际值编入索引的字典以存储结果:

 将numpy导入为np来自集合的
导入defaultdict
的行数= 64
ncolumns = 16384
fk = np.fft.fftfreq(行数)
fq = np.fft.fftfreq(ncolumns)
#在这里使用随机数简化示例
#实际上S是几次FFT和复数乘法的结果
S = np.random.random(size =(nrows,ncolumns)) + 1j * np.random.random(size =(nrows,ncolumns))

ret = defaultdict(lambda:{ fi:[], Z:[]})
对于范围内的k(-nrows // 2,nrows // 2):
对于范围内的q((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之类的对象进行交互和可视化。



注意:这与另一个问题。由于这是关于存储结果的,所以我认为最好创建两个单独的问题。

解决方案

事实证明,<对优化相关问题的a href = https://stackoverflow.com/questions/61104413/optimizing-an-array-mapping-operation-in-python>答案有效地解决了我的问题存储数据。新代码返回f i ,%alpha; j 的二维数组,这些数组可用于直接索引S。因此,获取%的S的所有值alpha; j = 0,例如,一个人可以做

  S [alphaj == 0] 

我可以非常有效地使用它,这似乎是创建合理数据结构的最快方法。 / p>

I have two arrays that are related to each other via a mapping operation. I will call them S(fk,fq) and Z(fij). The arguments are all sampling frequencies. The mapping rule is fairly straightforward:

fi = 0.5 · (fk - fq)
αj = fk + fq

S is the result of several FFTs and complex multiplications and is defined on a rectangular grid. However, Z is defined on a diamond-shaped grid and it is not clear to me how best to store this. The image below is an attempt at visualizing the operation for a simple example of a 4×4 array, but in general the dimensions are not equal and are much larger (maybe 64×16384, but this is user-selectable). Blue points are the resulting values of fi and αj and the text describes how these are related to fk, fq, and the discrete indices. The diamond-shaped nature of Z means that in one "row" there will be "columns" that fall in between the "columns" of adjacent "rows". Another way to think of this is that fi can take on fractional index values!

Note that using zero's or nan's to fill in elements that don't exist in any given row has two drawbacks 1) it inflates the size of what may already be a very large 2-D array and 2) it does not really represent the true nature of Z (e.g. the array size will not really be correct).

Currently I am using a dictionary indexed on the actual values of αj to store the results:

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)

I still find this a bit cumbersome to work with and wonder if anyone has suggestions for a better approach? "Better" here would be defined as more computationally and memory efficient and/or easier to interact with and visualize using something like matplotlib.

Note: This is related to another question about how to get rid of those nasty for-loops. Since this is about storing the results I thought it would be better to create two separate questions.

解决方案

It turns out that the answer to a related question on optimization effectively solved my problem of how to better store the data. The new code returns 2-D arrays for fi, %alpha;j, and these can be used to directly index S. So to get all values of S for %alpha;j = 0, for example, one can do

S[alphaj == 0]

I can use this pretty effectively and it seems like the quickest way to create a reasonable data structure.

这篇关于Python中菱形数组的数据结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆