我有一个以下形式的 .txt 文件:
header line 1
header line 2
x1 y1 x4 y4 x7 y7
x2 y2 x5 y5 x8 y8
x3 y3 x6 y6 x9 y9
footer line
x 和 y 值将由制表符分隔,在我的例子中是“2,9”形式的数字(包括最后一个空格)。示例:
header line 1
header line 2
1,0 1,5 4,0 4,5 7,0 7,5
2,0 2,5 5,0 5,5 8,0 8,5
3,0 3,5 6,0 6,5 9,0 9,5
footer line
文件以
latin-1
编码。我正在寻找一种简单的方法来将我的 x 和 y 的 numpy 数组转换为浮点数,即:
array([1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0])
y 也类似。
我首先创建了一个函数来用“.”替换“,”。并删除尾随空格:
import numpy as np
def ctf(valstr):
return float(valstr.replace(',','.').replace(" ",""))
然后定义了一个可变长度的字典供以后使用:
def dic(length):
dic={}
for i in range(0,length):
dic[i]=ctf
return dic
然后我可以“手动”阅读各列并将它们连接在一起:
xval1,yval1,xval2,yval2,xval3,yval4=np.genfromtxt("file.txt",delimiter="",unpack=True,skip_header=2,skip_footer=1,encoding="latin-1",converters=dic(6))
xvalues=np.concatenate((xval1,xval2,xval3))
yvalues=np.concatenate((yval1,yval2,yval3))
它可以工作,但不太漂亮,特别是如果我有更多的列。我想要的是一种只需要指定总列数(在上面 6 的情况下)和我想要获取的数组数量(在我的示例 2 中)的方法。
注意:我认为转换器/字典部分实际上与我的问题无关。我包含它是因为我需要任何替代解决方案才能使用转换器或以其他方式实现相同的结果。
您可以使用 Pandas 仅导入文件中的相关行,然后将列展平为 numpy 数组:
import pandas as pd
df = pd.read_csv("file.txt", header=None, skiprows=2, skipfooter=1, sep=r"\s+")
df = df.replace(",", ".", regex=True).astype(float)
n = 2
arrays = [df.iloc[:, i::n].to_numpy().flatten(order="F") for i in range(n)]
[array([1., 2., 3., 4., 5., 6., 7., 8., 9.]), array([1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5])]
您的文本示例:
In [33]: txt='''header line 1
...: header line 2
...: 1,0 1,5 4,0 4,5 7,0 7,5
...: 2,0 2,5 5,0 5,5 8,0 8,5
...: 3,0 3,5 6,0 6,5 9,0 9,5
...: footer line'''.splitlines()
对于浮点转换,您无需担心尾随空白:
In [34]: def ctf(valstr):
...: return float(valstr.replace(',','.'))
...:
In [35]: def dic(length):
...: dic={}
...: for i in range(0,length):
...: dic[i]=ctf
...: return dic
...:
加载到一个二维数组中:
In [36]: data=np.genfromtxt(txt,skip_header=2,skip_footer=1,encoding="latin-1",converters=dic(6))
In [37]: data
Out[37]:
array([[1. , 1.5, 4. , 4.5, 7. , 7.5],
[2. , 2.5, 5. , 5.5, 8. , 8.5],
[3. , 3.5, 6. , 6.5, 9. , 9.5]])
然后拆分为每隔一列:
In [38]: data[:,::2]
Out[38]:
array([[1., 4., 7.],
[2., 5., 8.],
[3., 6., 9.]])
In [39]: data[:,::2].ravel(order='F')
Out[39]: array([1., 2., 3., 4., 5., 6., 7., 8., 9.])
In [40]: data[:,1::2].ravel(order='F')
Out[40]: array([1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5])
我使用
order='F'
与其他答案相同。我的 data
与他们的 tonumpy()
数组类似。
如果我保留
unpack
,data
就是转置,我们可以从中选择每隔一行:
In [41]: data=np.genfromtxt(txt,skip_header=2,skip_footer=1,encoding="latin-1",converters=dic(6),unpack=True)
In [42]: data
Out[42]:
array([[1. , 2. , 3. ],
[1.5, 2.5, 3.5],
[4. , 5. , 6. ],
[4.5, 5.5, 6.5],
[7. , 8. , 9. ],
[7.5, 8.5, 9.5]])
In [43]: data[::2,:]
Out[43]:
array([[1., 2., 3.],
[4., 5., 6.],
[7., 8., 9.]])
In [44]: data[::2,:].ravel()
Out[44]: array([1., 2., 3., 4., 5., 6., 7., 8., 9.])
我还可以获得
data
作为数组列表,并连接所有其他数组:
In [49]: [*data]=np.genfromtxt(txt,skip_header=2,skip_footer=1,encoding="latin-1",converters=dic(6),unpack=True)
In [50]: data
Out[50]:
[array([1., 2., 3.]),
array([1.5, 2.5, 3.5]),
array([4., 5., 6.]),
array([4.5, 5.5, 6.5]),
array([7., 8., 9.]),
array([7.5, 8.5, 9.5])]
In [51]: data[::2]
Out[51]: [array([1., 2., 3.]), array([4., 5., 6.]), array([7., 8., 9.])]
In [52]: np.concatenate(data[::2])
Out[52]: array([1., 2., 3., 4., 5., 6., 7., 8., 9.])
这只是您
manual
拆包的简化。