我的数据文件是按列分隔的,
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数组?
答案 0 :(得分:0)
尝试:
data[:, 0].astype(np.double)
通常情况下,将字符串留在内存中并不是一个好主意。至少考虑使用numpy结构数组,并且可能只使用x y z列的系数,这样就可以将它们存储为内存中的整数/双数。
答案 1 :(得分:0)
这里有一系列操作,可以将您的示例文本转换为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()
让genfromtxt
为每列分配dtypes。结果是一个结构化数组,其中包含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
逐个转换字符串值。
要将整个数组转换为2d数字数组,请创建一个空数组以保存转换后的数据
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
等可接受字符串的函数。