将坐标元组信息转换为numpy数组

时间:2013-02-27 14:38:14

标签: python numpy scipy

我得到了有限元程序的结果,该程序在三维空间中的规则间隔的网格位置处给出各种感兴趣的测量值(例如,温度,密度,压力)。

值沿每个坐标均匀分布,但不同坐标的间距可能不同。例如,

x1 = [0, 0.1, 0.2, ..., 1.0]      (a total of NX1 pts) 
x2 = [0, 0.5, 1.0, ..., 20]       (a total of NX2 pts) 
x3 = [0, 0.2, 0.4, ..., 15]       (a total of NX3 pts)

软件输出的结果如下:

x1_1, x2_1, x3_1, f_x, g_x, h_x
x1_1, x2_1, x3_2, f_x, g_x, h_x
x1_1, x2_1, x3_3, f_x, g_x, h_x
...
x1_1, x2_2, x3_1, f_x, g_x, h_x
x1_1, x2_2, x3_2, f_x, g_x, h_x
x1_1, x2_2, x3_3, f_x, g_x, h_x
...
x1_2, x2_1, x3_1, f_x, g_x, h_x
x1_2, x2_1, x3_2, f_x, g_x, h_x
x1_2, x2_1, x3_3, f_x, g_x, h_x
...

其中f_x,g_x,h_x是特定网格点感兴趣的度量。

我想转换上面的数据格式并获得f,g和h的(NX1 x NX2 x NX3)numpy数组。

某些结果集相当大(80 x 120 x 100)。

是否有人有任何提示以有效的方式进行此转换?

2 个答案:

答案 0 :(得分:1)

假设您将整个数组作为形状data的数组(Nx1 * Nx2 * Nx3, 6)读入内存。

data = np.loadtxt('data.txt', dtype=float, delimiter=',')

如果您的示例显示,点数是按字典顺序生成的,您只需要将列抓取到fgh并重新整形:

f = data[:, 3].reshape(Nx1, Nx2, Nx3)
g = data[:, 4].reshape(Nx1, Nx2, Nx3)
h = data[:, 5].reshape(Nx1, Nx2, Nx3)

如果您需要确定Nx1Nx2Nx3是什么,可以使用np.unique

Nx1 = np.unique(data[:, 0]).shape[0]
Nx2 = np.unique(data[:, 1]).shape[0]
Nx3 = np.unique(data[:, 2]).shape[0]

如果无法保证点的顺序,则可以使用np.unique将索引提取到网格值,这是一个更强大的解决方案:

Nx1, idx1 = np.unique(data[:, 0], return_inverse=True)
Nx1 = Nx1.shape[0]
Nx2, idx2 = np.unique(data[:, 1], return_inverse=True)
Nx2 = Nx2.shape[1]
Nx3, idx3 = np.unique(data[:, 2], return_inverse=True)
Nx3 = Nx3.shape[0]

f = np.empty((Nx1, Nx2, Nx3))
f[idx1, idx2, idx3] = data[:, 3]
g = np.empty((Nx1, Nx2, Nx3))
g[idx1, idx2, idx3] = data[:, 4]
h = np.empty((Nx1, Nx2, Nx3))
h[idx1, idx2, idx3] = data[:, 5]

这将为fgh创建新数组,而不是原始data数组的视图,因此它将使用更多内存。

当然,除了上面丑陋的代码重复所有内容三次之外,你应该使用循环或列表理解!

答案 1 :(得分:0)

无论如何都必须遍历整个文件,为什么不只是初始化数组并输入值?

棘手的部分是,如果你想要一个形状为(NX1,NX2,NX3)的数组,但如果你的x1,x2,x3值是float s,那么你必须以某种方式索引你的数组。也许存在一个数据结构,但你可以使用像

这样的东西
def xyz_index((x,y,z),(n1,n2,n3)):
    """ return integer indices for x,y,z position
        given a constant step """
    return tuple(map(int,[x/n1,y/n2,z/n3]))

import numpy as np
NX1,NX2,NX3 =  (80, 120, 100)
ns = n1, n2, n3 =   (.1,.5,.2)
x1, x2, x3 = np.arange(0,1+n1,n1), np.arange(0,20+n2,n2), np.arange(0,15+n3,n3),

data = np.empty((NX1,NX2,NX3),dtype=[('f',float),('g',float),('h',float)])
with open(filename,'r') as f:
    for line in f:
        x,y,z,f,g,h = map(float,line.split(', '))
        data[xyz_index((x,y,z),ns)] = (f,g,h)

然后您可以按如下方式访问您的数据:

对于h - x1,x2,x3 = .2, .5, 0.点的值,请使用

data[xyz_index((.2,.5,0),ns)]['h']

如果没有['h'],则会返回(f,g,h)元组,上面有dtype

如果没有索引,它将返回所有(NX1,NX2,NX3) - 值的h数组。


现在我看一下,如果n1, n2, n3总是一样的话你可能想要在你的xyz_index函数中定义它们那么你就不必通过每次ns

data[xyz_index(.2,.5,0)]['h']