3

我的教授使用 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跳过第二列-第六列,然后将数据类型F(浮点)分配给第七列,等等。然后分配sn到没有跳过的第一列,等等。

我一直在尝试通过使用numpy.loadtxt("sn-full.txt")or来复制它,ascii.read("sn-full.txt")但我不确定如何输入 dtype 参数。我知道我可以将所有内容分配为某种数据类型,但是如何将数据类型分配给各个列?

4

3 回答 3

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。只要每一行都具有相同的模式,三个空格分隔的列将超新星名称和星系名称表示为两个单词,那么你就可以了。但是,如果任何星系名称都是一个单词,那么解析将失败。我怀疑如果 IDLreadcol正常工作,那么相应的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),
              )
于 2013-10-23T00:09:51.470 回答
2

http://casa.colorado.edu/~ginsbura/pyreadcol.htm看起来像你想要的。它模拟 IDL 的 readcol 函数。

另一种可能性是https://pypi.python.org/pypi/fortranformat。看起来它可能功能更强大,并且您正在查看的数据采用固定格式,并且格式说明符(X、A 等)是 fortran 格式说明符。

于 2013-10-22T22:38:06.197 回答
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, ...},)

(这里的字符串属于一般的“对象”数据类型)。

现在每列都有一个名称,可以作为 访问mydata['colname'],然后可以像常规的 numpy 1D 数组一样切片,例如mydata['colname'][20:50]等。

Pandas 具有对 matplotlib 的内置绘图调用,因此您可以通过 快速获得数值类型列的概览mydata['column'].plot(),或者通过mydata.plot('col1', 'col2'). 可以传递所有正常的绘图关键字。

如果要在普通的 matplotlib 例程中绘制数据,只需将列传递给 matplotlib,它们将被视为普通的 Numpy 向量。每一列都可以作为一个普通的 Numpy 向量作为mydata['colname'].values.

编辑

如果你的数据没有统一分隔,numpy的genfromtxt()功能更好。然后,您可以通过以下方式将其转换为 Pandas DataFrame

mydf = pd.DataFrame(myarray, columns=['col1', 'col2', ...],
                    dtype={'col1':sp.float64, 'col2':object, ...})
于 2013-10-23T17:22:19.307 回答