我的教授使用IDL并向我发送了一份我需要最终能够阅读和操作的ASCII数据文件。
他使用以下命令读取数据:
readcol, 'sn-full.txt', format='A,X,X,X,X,X,F,A,F,A,X,X,X,X,X,X,X,X,X,A,X,X,X,X,A,X,X,X,X,F,X,I,X,F,F,X,X,F,X,F,F,F,F,F,F', $
sn, off1, dir1, off2, dir2, type, gal, dist, htype, d1, d2, pa, ai, b, berr, b0, k, kerr
以下是前两行的图片:http://i.imgur.com/hT7YIE3.png
由于我不会成为天文学家,我使用的是Python,但由于我是新手,我很难读取数据。
我知道他的代码将数据类型A(字符串数据)分配给第一列,使用X跳过第二列-six,然后将数据类型F(浮点)分配给第七列,等等。然后sn被分配给未跳过的第一列,等等。
我一直在尝试使用numpy.loadtxt("sn-full.txt")
或ascii.read("sn-full.txt")
复制此内容,但我不确定如何输入dtype参数。我知道我可以将所有内容分配为某种数据类型,但如何将数据类型分配给各个列?
答案 0 :(得分:4)
使用astropy.io.ascii
,您应该能够相对轻松地阅读文件:
from astropy.io import ascii
# Give names for ALL of the columns, as there is no easy way to skip columns
# for a table with no column header.
colnames = ('sn', 'gal_name1', 'gal_name2', 'year', 'month', 'day', ...)
table = ascii.read('sn_full.txt', Reader=ascii.NoHeader, names=colnames)
这将为您提供包含所有数据列的表格。你有一些你不需要的列的事实不是问题,除非表是超长行。对于您显示的表格,您无需明确指定dtypes,因为io.ascii.read
会正确地指出它们。
这里的一个小问题是,您显示的表实际上是一个固定宽度的表,这意味着所有列都垂直排列。请注意,第一行以1998S NGC 3877
开头。只要每一行都有相同的模式,三个以空格分隔的列表示超新星名称和星系名称为两个单词,那么你就没事了。但是如果任何一个星系名称只是一个单词,则解析将失败。我怀疑如果IDL readcol
正在运行,那么相应的io.ascii
版本应该开箱即用。如果没有,则io.ascii
有一种方法可以读取固定宽度表,您可以在其中明确提供列名和位置。
[编辑] 在这种情况下看起来需要固定宽度的读取器来通知解析器如何拆分列而不是仅使用空格作为分隔符。所以基本上你需要在表文件的顶部添加两行,其中第一行给出列名,第二行有破折号,表示每列的跨度:
a b c
---- ------------ ------
1.2 hello there 2
2.4 worlds 3
如果您没有修改输入数据文件的选项,astropy.io.ascii
中也可以通过代码指定每列的开始和停止位置,例如:
>>> ascii.read(table, Reader=ascii.FixedWidthNoHeader,
names=('Name', 'Phone', 'TCP'),
col_starts=(0, 9, 18),
col_ends=(5, 17, 28),
)
答案 1 :(得分:2)
http://casa.colorado.edu/~ginsbura/pyreadcol.htm看起来像你想要的那样。它模仿IDL的readcol函数。
另一种可能性是https://pypi.python.org/pypi/fortranformat。看起来它可能更有能力,你正在查看的数据是固定格式的,格式说明符(X,A等)是fortran格式说明符。
答案 2 :(得分:0)
我会将Pandas用于特定目的。最简单的方法是,假设您的列是单标签分隔的:
import pandas as pd
import scipy as sp # Provides all functionality from numpy, too
mydata = pd.read_table(
'filename.dat', sep='\t', header=None,
names=['sn', 'gal_name1', 'gal_name2', 'year', 'month',...],
dtype={'sn':sp.float64, 'gal_name1':object, 'year':sp.int64, ...},)
(这里的字符串属于一般的'object'数据类型。)
每个列现在都有一个名称,可以作为mydata['colname']
进行访问,然后可以像普通的numpy 1D数组一样切片,例如mydata['colname'][20:50]
等等。
Pandas内置了对matplotlib的绘图调用,因此您可以快速获取mydata['column'].plot()
的数值类型列的概述,或者mydata.plot('col1', 'col2')
的两个不同的列。所有正常的绘图关键字都可以通过。
如果你想在普通的matplotlib例程中绘制数据,你可以将列传递给matplotlib,在那里它们将被视为普通的Numpy向量。
每个列都可以作为mydata['colname'].values
的普通Numpy向量进行访问。
修改强>
如果您的数据没有统一分离,那么numpy的genfromtxt()
功能会更好。然后,您可以通过
mydf = pd.DataFrame(myarray, columns=['col1', 'col2', ...],
dtype={'col1':sp.float64, 'col2':object, ...})