2015-07-13 26 views
2

我有一個巨大的一組目錄有不同的列和每個列不同的標題名稱,每個標題名稱的描述作爲註釋給出我的ascii文件連續開始。將它們讀入pandas.DataFrame的最佳方法是什麼,同時它可以設置列的名稱,而無需從頭開始定義它。以下是我的目錄的例子:閱讀一個ascii文件,頭部給出的標題爲一個熊貓數據框

# 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 
+0

我們可以在這個問題上得到更多的限制嗎? (例如,我們應該預計什麼是最大列數?) –

+0

@PaulH從23000行的順序! – Dalek

+0

你有23,000列的文件? –

回答

2

好吧,假設你所有的頭信息中完全相同的方式編碼的,這裏是我會怎麼做:

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_AUTO Kron-like elliptical aperture magnitude [mag]

['#', '1', 'MAG_AUTO', 'Kron-like', 'elliptical', 'aperture', 'magnitude', '[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 
+1

您正在跳過第一行數據。當你找到一行不以'#'開始的行時,你必須在數據中包含該行。 –

+0

啊,很好,@WarrenWeckesser。我的第一個想法是打破循環,用'skiprows'參數將整個文件送回'read_table'。思考? –

+0

@PaulH答案還存在問題。對於最後一列中的第一行數據,我有:'df ['CLASS_STAR'] [0] '0.0286538 \ n'' – Dalek

9

這是Sextractor格式的文件。該astropy.io.asciireader本身理解這種格式,所以這是一個管理單元,以閱讀:

>>> 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 
... 

注意,當使用ASCII astropy讀者你得到一個表,也保留了單元的元數據。

如果您仍想將其轉換爲容易的的熊貓數據框。 astropy版本1.1(和當前主版本)的方法有to_pandasfrom_pandas,這使得此轉換更健壯(請參閱http://astropy.readthedocs.org/en/latest/table/pandas.html)。

+1

我不是天文學家,但是天文學似乎是一個很好的資源。 –

相關問題