2013-02-27 146 views
3

我得到了一个有限元程序的结果,该程序在三维空间中规则间隔的网格位置给出各种感兴趣的度量(例如,温度,密度,压力)。将坐标元组信息转换为numpy数组

值沿着每个坐标等距间隔,但是这个间距对于不同的坐标可能是不同的。例如,从软件输出

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是在特定的网格点利益的措施。

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

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

有没有人有任何提示,以有效的方式做这种转换?

+0

有没有办法以Python代码的形式提供一些小样本数据来说明你的问题?我不确定我是否理解你的输出格式,当你说你想要阵列“for”f,g和h时,你的意思是什么。 – YXD 2013-02-27 15:05:50

回答

1

让我们假设你将整个数组作为的形式(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数组,所以会使用更多的内存。

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

+0

不是所有对'data [n]'的引用都给出第n行而不是列?我应该认为它们中的大多数应该被替换为'data [:,n]' – askewchan 2013-02-27 16:44:47

+0

@askwechan是的! – Jaime 2013-02-27 17:15:25

+1

@askewchan我已经编辑过,但是,为了简单起见,最好在调用'np.loadtxt'时简单地设置'unpack = True',这相当于做'data = data.T',并且保持原样。 – Jaime 2013-02-27 17:18:20

0

无论如何,你必须循环遍历整个文件,为什么不直接初始化数组并输入值呢?

棘手的部分是,如果你想与形状(NX1,NX2,NX3)数组,但如果你的x1,x2,x3float S,那么你必须索引你的阵列莫名其妙。也许一个数据结构存在这一点,但你可以usome像

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) 

然后,您可以通过以下方式访问您的数据:

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

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

没有['h'],这将返回一个(f,g,h)元组与上面的dtype

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


现在,我看它,如果n1, n2, n3总是你可能要定义它们xyz_index功能,那么你就不必通过ns每次都一样:

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