将eval函数应用于numpy数组



我的数据文件是列分隔的,

0   0   0   0.00   0.00   0.00   x1  y1  z1
0   0   0   0.75   0.75   0.00   -x1  -y1  z1

我想读取这个文件,并使用numpy数组进行一些列操作。这里,x1,y1,z1是程序中定义的变量。所以我的代码是

import numpy as np
x1,y1,z1=0.5,0.5,0.5
data=np.genfromtxt("./inputfile",dtype=str)
coordinate=data[:,0]+data[:,6]

但是出现错误,

File "/home/hermite/Codes/spinel.py", line 4, in <module>
TypeError: unsupported operand type(s) for +: 'numpy.ndarray' and 'numpy.ndarray'

我理解为什么会出现这种错误,因为对于字符串数据类型,不允许+操作。所以我必须将数据数组更改为数字。我尝试了eval()函数,但这不适用于numpy数组。。所以我的问题是,如何将eval()函数应用于numpy数组?

以下是一系列操作,这些操作将把示例文本转换为一个2d numpy数组,并在此过程中填充x1、y1、z1的值。这些是ipython会话中的行。

通过剪切和粘贴文本模拟从文件读取

In [109]: txt=b"""0   0   0   0.00   0.00   0.00   x1  y1  z1
0   0   0   0.75   0.75   0.00   -x1  -y1  z1"""    
In [110]: txt=txt.splitlines()

让CCD_ 1为每列分配数据类型。结果是一个混合了int、float和string列(或字段)的结构化数组:

In [111]: data=np.genfromtxt(txt,dtype=None)    
In [112]: data
Out[112]: 
array([(0, 0, 0, 0.0, 0.0, 0.0, b'x1', b'y1', b'z1'),
(0, 0, 0, 0.75, 0.75, 0.0, b'-x1', b'-y1', b'z1')], 
dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', '<i4'), ('f3', '<f8'), ('f4', '<f8'), ('f5', '<f8'), ('f6', 'S3'), ('f7', 'S3'), ('f8', 'S2')])

然后可以使用计算您的coordinate

In [137]: coordinate=data['f0']+[eval(a) for a in data['f6']]
# array([ 0.5, -0.5])

我通过字段名访问字段,并使用eval逐个转换字符串值。

要将整个数组转换为二维数字数组,请制作一个空数组来保存转换后的数据

In [113]: data1=np.zeros((2,9),float)

用一个简单的副本填写数字列:

In [114]: for i in range(6):
data1[:,i]=data[data.dtype.names[i]]
.....:     
# or `data1[:,:6]=data[list(data.dtype.names[:6])].tolist()` 

对于字符串列,通过eval:分别传递值

In [115]: x1,y1,z1=.25,.5,.75    
In [116]: for i in range(6,9):
data1[:,i]=[eval(a) for a in data[data.dtype.names[i]]]
.....:     

结果数据:

In [117]: data1
Out[117]: 
array([[ 0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.  ,  0.25,  0.5 ,  0.75],
[ 0.  ,  0.  ,  0.  ,  0.75,  0.75,  0.  , -0.25, -0.5 ,  0.75]])

eval(a)可以被一个更安全的函数所取代,例如一个只解释像x1这样的可接受字符串的函数。

尝试:data[:, 0].astype(np.double)

仅供参考,一般来说,在内存中留下这样的字符串不是一个好主意。至少考虑使用numpy结构数组,并可能只使用x y z列的系数,这样您就可以将它们作为整数/双精度存储在内存中。

最新更新