2017-04-04 57 views
0

我有了3條線的數據,看起來像這樣的ASCII文件:讀取丟失單元格的ascii數據行?

Timestamp: 00:47:14 SATID 13 VAL1 28 VAL2 227 SIGNAL 37          SATID 15 VAL1 22 VAL2 265 SIGNAL 30 SATID 16 VAL1 22 VAL2 265 SIGNAL 30 
Timestamp: 00:48:14 SATID 13 VAL1 28 VAL2 227 SIGNAL 37          SATID 15 VAL1 22 VAL2 265 SIGNAL nan SATID 16 VAL1 22 VAL2 265 SIGNAL 30 
Timestamp: 00:49:14          SATID 14 VAL1 22 VAL2 265 SIGNAL 30 

(請參閱原始格式圖像)。 original ascii data format當我嘗試把它讀成Python,不過,我得到以下錯誤:

time,sat1,sat2,sat3,sat4 = np.loadtxt("test1.asc", usecols=(1,9,17,25,33), unpack=True, converters = {1: strpdate2num("%H:%M:%S")}) 
Traceback (most recent call last): 
File "<stdin>", line 1, in <module> 
File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/numpy/lib/npyio.py", line 839, in loadtxt 
vals = [vals[i] for i in usecols] 
IndexError: list index out of range 

有誰知道我怎麼能做到這樣Python忽略空單元格和讀取任何數據可在每列?

謝謝!

+0

在你的文件列寬度固定。你可能應該使用熊貓的'pd.read_fwf()'。 – DyZ

+0

嗨DYZ。不幸的是,列有時會有稍微不同的寬度... – luke

+0

相鄰列中的值是否重疊?如果沒有(如你的例子),你仍然可以將它們視爲固定寬度。 – DyZ

回答

0

沒有抓住numpypandas,讓我們看看我們如何閱讀「手動

首先認識到,時間戳總是在同一個地方,同" SATID "以下,所以你可以做一個.split(' SATID ')[0]得到該信息。

然後,看起來如果您對信息的其餘部分執行.split(' SATID '),則會獲得所有必需的信息,然後您可以進一步分割。

代碼,這將是這個樣子:

raw_data = ["Timestamp: 00:47:14 SATID 13 VAL1 28 VAL2 227 SIGNAL 37          SATID 15 VAL1 22 VAL2 265 SIGNAL 30 SATID 16 VAL1 22 VAL2 265 SIGNAL 30", 
      "Timestamp: 00:48:14 SATID 13 VAL1 28 VAL2 227 SIGNAL 37          SATID 15 VAL1 22 VAL2 265 SIGNAL nan SATID 16 VAL1 22 VAL2 265 SIGNAL 30", 
      "Timestamp: 00:49:14          SATID 14 VAL1 22 VAL2 265 SIGNAL 30"] 

output = [] 
for line in raw_data: 
    if 'SATID' in line: #making sure it is not an empty line 
     timestamp = line.split(' SATID ')[0].split('Timestamp: ')[1].rstrip(' ') 
     data = line.split(' SATID ')[1:] 
     for record in data: 
      if 'VAL1' in record: #making sure it is not an empty record 
       satid = record.split(' VAL1 ')[0] 
       val1 = record.split(' VAL1 ')[1].split(' VAL2 ')[0] 
       val2 = record.split(' VAL2 ')[1].split(' SIGNAL ')[0] 
       signal = record.split(' SIGNAL ')[1].rstrip(' ') 
       output.append({'Timestamp':timestamp, 
           'SATID':satid, 
           'VAL1':val1, 
           'VAL2':val2, 
           'SIGNAL':signal}) 


# output is now a list of dictionaries 
for d in output: 
    print(d) 
+0

謝謝埃德溫...看起來像一種內源方法。但是,有一個問題:我怎樣才能保證每一列都被保留下來,並且我可以將它的內容分配給一個特定的變量,例如最初顯示的例子中? (見上面的time,sat1,sat2,sat3,sat4) – luke

+0

你可以用'詞典列表'來做任何你想做的事情,或者你可以在循環做自己的事情時修改,你可以這樣做,而不是輸出。追加()'。請記住,第一個循環是逐行的,爲了獲得時間戳,第二個循環是在該行中逐個記錄的。這個例子只是爲了讓你思考,只使用標準函數,你真的應該看看熊貓,這是在其中一個評論中提到的。 –

0

由於列邊緣不相交,你可以把你的文件爲固定寬度的文件和使用功能read_fwf。您將不得不準備列規範列表 - 指定每列的第一個和最後一個位置的元組列表。這裏是開始規格的的(它是枯燥的,但你必須做一次):

specs = [(0,11),(11,20),(20,26),(26,29),(29,33),(33,37), 
     (37,42),(42,45),(45,52),(52,55),(55,61),(61,63)] 
pd.read_fwf('foo.txt',header=None,colspecs=specs) 
#   0   1  2  3  4  5  6  7  8  9 \ 
#0 Timestamp: 00:47:14 SATID 13.0 VAL1 28.0 VAL2 227.0 SIGNAL 37.0 
#1 Timestamp: 00:48:14 SATID 13.0 VAL1 28.0 VAL2 227.0 SIGNAL 37.0 
#2 Timestamp: 00:49:14 NaN NaN NaN NaN NaN NaN  NaN NaN 

#  10 11 
#0 NaN NaN 
#1 NaN NaN 
#2 SATID 1.0