Python 将头在第一行中给定的ascii文件读入数据帧

Python 将头在第一行中给定的ascii文件读入数据帧,python,numpy,pandas,astropy,Python,Numpy,Pandas,Astropy,我有一个巨大的目录集,它有不同的列和每列不同的标题名,其中每个标题名的描述在我的ascii文件的开头以注释的形式给出。将它们读入pandas.DataFrame的最佳方法是什么?它还可以设置列的名称,而无需从头定义。以下是我的目录示例: # 1 MAG_AUTO Kron-like elliptical aperture magnitude [mag] # 2 rh half light radius (analys

我有一个巨大的目录集,它有不同的列和每列不同的标题名,其中每个标题名的描述在我的ascii文件的开头以注释的形式给出。将它们读入pandas.DataFrame的最佳方法是什么?它还可以设置列的名称,而无需从头定义。以下是我的目录示例:

#   1 MAG_AUTO            Kron-like elliptical aperture magnitude         [mag]
#   2 rh                  half light radius (analyse)                     [pixel]
#   3 MU_MAX              Peak surface brightness above background        [mag * arcsec**(-2)]
#   4 FWHM_IMAGE          FWHM assuming a gaussian core                   [pixel]
#   5 CLASS_STAR          S/G classifier output                          
18.7462 4.81509 20.1348 6.67273 0.0286538
18.2440 7.17988 20.6454 21.6235 0.0286293
18.3102 3.11273 19.0960 8.26081 0.0430532
21.1751 2.92533 21.9931 5.52080 0.0290418
19.3998 1.86182 19.3166 3.42346 0.986598
20.0801 3.52828 21.3484 6.76799 0.0303842
21.9427 2.08458 22.0577 5.59344 0.981466
20.7726 1.86017 20.8130 3.69570 0.996121
23.0836 2.23427 23.3689 4.49985 0.706207
23.2443 1.62021 23.1089 3.54191 0.973419
20.6343 3.99555 21.9426 6.94700 0.0286164
23.4012 2.00408 23.3412 4.35926 0.946349
23.8427 1.54819 23.8241 3.83407 0.897079
20.3344 2.69910 20.9401 4.38988 0.0355277
21.7506 2.43451 22.2115 4.62045 0.0786921

好的,假设您的所有标题信息都以完全相同的方式编码,下面是我将如何做到这一点:

import re

import pandas

COMMENT_CHAR = '#'
columns = []
with open('test.dat', 'r') as td:
    for line in td:

        # find the commented lines
        if line[0] == COMMENT_CHAR:
            info = re.split(' +', line)
            columns.append(info[2])

        # when we seethe first line that doesn't start with 
        # COMMENT_CHAR, we pass the remaining lines of the 
        # file to pandas.read_table and break our loop
        else:
            _dfs = [
                pandas.DataFrame([line.split(' ')], columns=columns, dtype=float),
                pandas.read_table(td, sep='\s', header=None, names=columns)
            ]
            df = pandas.concat(_dfs, ignore_index=True)
要稍微分解初始解析,
re.split(“+”,line)
将此转换为:

#1 MAG#u AUTO-Kron-like椭圆孔径大小[MAG]

进入

因此,我们将列名作为3个元素(index=2)

所有这些都会生成一个如下所示的数据帧:

print(df.head())
   MAG_AUTO       rh   MU_MAX  FWHM_IMAGE  CLASS_STAR
0   18.7462  4.81509  20.1348     6.67273    0.0286538
1   18.2440  7.17988  20.6454    21.62350    0.028629
2   18.3102  3.11273  19.0960     8.26081    0.043053
3   21.1751  2.92533  21.9931     5.52080    0.029042
4   19.3998  1.86182  19.3166     3.42346    0.986598
df.info()
为我们提供了:

<class 'pandas.core.frame.DataFrame'>
Int64Index: 15 entries, 0 to 14
Data columns (total 5 columns):
MAG_AUTO      15 non-null float64
rh            15 non-null float64
MU_MAX        15 non-null float64
FWHM_IMAGE    15 non-null float64
CLASS_STAR    15 non-null float64
dtypes: float64(5)
memory usage: 720.0 bytes

INT64索引:15个条目,从0到14
数据列(共5列):
MAG_自动15非空浮点64
rh 15非空浮点64
MU_最大值15非空浮点64
FWHM_图像15非空浮点64
类_星15非空浮点64
数据类型:float64(5)
内存使用:720.0字节

这是一个Sextractor格式的文件。
astropy.io.ascii
本机理解此格式,因此这是一个快速阅读:

>>> from astropy.io import ascii
>>> dat = ascii.read('table.dat')
>>> dat
<Table masked=False length=3>
MAG_AUTO    rh       MU_MAX    FWHM_IMAGE CLASS_STAR
  mag            mag / arcsec2    pix               
float64  float64    float64     float64    float64  
-------- ------- ------------- ---------- ----------
 18.7462 4.81509       20.1348    6.67273  0.0286538
  18.244 7.17988       20.6454    21.6235  0.0286293
 18.3102 3.11273        19.096    8.26081  0.0430532
...
>>从astropy.io导入ascii
>>>dat=ascii.read('table.dat')
>>>dat
MAG_自动右侧MU_最大半高宽_图像等级_星形
mag mag/ARCEC2 pix
浮动64浮动64浮动64浮动64浮动64浮动
-------- ------- ------------- ---------- ----------
18.7462 4.81509       20.1348    6.67273  0.0286538
18.244 7.17988       20.6454    21.6235  0.0286293
18.3102 3.11273        19.096    8.26081  0.0430532
...
请注意,使用astropy ASCII读卡器可以得到一个表,该表还保留了单位元数据


如果您仍然想将其转换为熊猫数据帧,那么使用
数据帧(dat.as_array())
也很容易。astropy的1.1版(以及当前的主版本)将有
到_pandas
自_pandas
的方法,使此转换更加健壮(请参见)。

我们可以在这个问题上获得更多约束吗?(例如,我们预期的最大列数是多少?@PaulH,从23000行开始!!你有23000列的文件吗?@PaulH抱歉,没有23000行,4到20列之间!查看我对注释的编辑您正在跳过第一行数据。当你发现一行不是以
#
开头时,你必须将该行包含在数据中。啊,捕捉得很好,@WarrenWeckesser。我的第一个想法是打破循环,使用
skiprows
参数将整个文件返回到
read_table
。想法?@PaulH答案中还有一个问题。对于最后一列中的第一行数据,我有:
df['CLASS_STAR'][0]'0.0286538\n'
@PaulH,第一行数据似乎是一个字符串。啊,我们可以告诉熊猫,一切都是一个浮点数(见最新编辑)。我不是天文学家,但天文学似乎是一个伟大的资源。