我的数据文件是列分隔的,
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列的系数,这样您就可以将它们作为整数/双精度存储在内存中。