我有以下问题。我在一个类中保存了大量数据。大多数这些数据都是时间相关的,在最复杂的情况下,变量是三维数组。
因为列表非常灵活(不需要显式声明),所以我想用它们来封装我的N维数组,因此,使用列表来保存时间依赖信息。
这里是我的列表中元素t = 0,t = 2和t = 3的典型示例,它位于历史类(float64的简单矩阵)中:
history.params[0]
array([[ 1. , 2. , 1. ],
[ 1. , 2. , 1. ],
[ 0.04877093, 0.53176887, 0.26210472],
[ 2.76110434, 1.3569246 , 3.118208 ]])
history.params[2]
array([[ 1.00000825, 1.99998362, 1.00012835],
[ 0.62113657, 0.47057772, 5.23074169],
[ 0.04877193, 0.53076887, 0.26210472],
[ 0.02762192, 4.99387138, 2.6654337 ]])
history.params[3]
array([[ 1.00005473, 1.99923187, 1.00008009],
[ 0.62713657, 0.47157772, 5.23074169],
[ 0.04677193, 0.53476887, 0.25210472],
[ 0.02462192, 4.89387138, 2.6654337 ]])
现在,我如何读取/提取矩阵的给定坐标(x,y)的所有元素,用于所有时间索引t?
我试着这样做:
history.params[:][0][0]
我得到了
array([ 1., 2., 1.])
实际上无论结肠的位置如何,我总是得到相同的值,它对应于我的矩阵的第一行:
"history.params[0][:][0]" returns "array([ 1., 2., 1.])" in the shell
"history.params[0][0][:]" returns "array([ 1., 2., 1.])"
为什么Python不能在这里区分矩阵的元素和列表的元素?什么是最好的解决方案?
当然,我可以编写一些循环并创建一个重新组织我的数据的新变量,但这有点浪费精力。我确信它存在一个优雅的解决方案。
PS:我要去Cythonize'我的代码在某些时候,所以如果你有一个优化的Cython解决方案来存储这些变量,我也很高兴听到它。答案 0 :(得分:2)
我建议使用numpy.array
数组而不是嵌套列表。
import numpy as np
# Create some data which would be equal to your "params"
a = np.array([[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]],
[[11, 12, 13],
[14, 15, 16],
[17, 18, 19]]])
print(a[0])
# [[1 2 3]
# [4 5 6]
# [7 8 9]]
print(a[:, 0, 0])
# [1, 11]
print(a[:, 0:2, 0])
# [[1, 4]
# [11, 14]]
此外,numpy可以与给定here的Cython结合使用。
答案 1 :(得分:0)
为什么Python不能在这里区分矩阵的元素和列表的元素?什么是最好的解决方案?
由于history.params[0]
是列表列表,因此history.params[0][0]
是一个列表,因此history.params[0][0][:]
是list[:]
,它是内部列表的副本。同样,history.params[0][:]
是列表列表的副本,因此history.params[0][:][0]
是(copy of the list of lists)[0]
,它再次是内部列表的第一行,但是在2D数组的副本中。
如果要展平列表,即将2D数组存储为一个列表,则尺寸为(n,m)
的2D数组的NxM
处的每个元素将成为展平数组中的元素(n*M + m)
。因此,在您发布的4x3中,元素(0,0)是平面列表的元素0,元素(2,1)是元素2 * 3 + 1 = 7,依此类推。
您可以将其扩展到3D数组:大小为KxNxM
的数组,您将索引(k,n,m)
为元素(k*N*M + n*N + m)
;同样对于更高的维度。