2017-02-22 39 views
1

我有如下文本文件。如何在特定條件下閱讀txt

A1 1234 56 
B2 1234 56 
C3 2345167 

我有startposition和length表。 其中每個元素代表每個元素在前一個df中的起始位置,以及每個行的長度。

start length 
1  1 
2  1 
3  1 
4  2 
6  2 
8  2 
10  1 

我想根據開始位置和長度來閱讀下面的內容。

A 1 nan 12 34 5 6 
B 2 nan 12 34 5 6 
C 3 nan 23 45 16 7 

第一,我試圖

pd.read_csv(file.txt,sep=" ")

但我不能想出如何分裂。

如何讀取和拆分數據框?

+0

這哪裏是 「下面」?你忽略了包括你的編碼嘗試。另外請注意,這是*不是* CSV格式的文件;它似乎只是文字。 – Prune

回答

1

這是一個固定寬度的文件,你可以使用pandas.read_fwf

import pandas as pd 
from io import StringIO 

s = StringIO("""A1 1234 56 
B2 1234 56 
C3 2345167""") 

pd.read_fwf(s, widths = widths.length, header=None) 

# 0 1 2 3 4 5 6 
#0 A 1 NaN 12 34 5 6 
#1 B 2 NaN 12 34 5 6 
#2 C 3 NaN 23 45 16 7 

widths數據幀:

widths = pd.read_csv(StringIO("""start length 
1  1 
2  1 
3  1 
4  2 
6  2 
8  2 
10  1"""), sep = "\s+") 
+0

我喜歡你的答案,比我的更好:)我可以提到你可能需要使用一個unicode字符串作爲'StringIO'來防止TypeError –

+0

@KJPhan謝謝!通常這不會導致問題,並且此處的StringIO僅用於演示目的。但是,是的,更嚴格的方式可能會將其聲明爲Unicode。感謝您指出。 – Psidom

2

正如評論中提到的,這不是CSV格式,所以我必須制定解決方法。

def get_row_format(length_file): 

    with open(length_file, 'r') as fd_len: 

     #Read in the file, not a CSV! 
     #this double list-comprehension produces a list of lists 
     rows = [[x.strip() for x in y.split()] for y in fd_len.readlines()] 

     #determine the row-format from the rows lists 
     row_form = {int(x[0]): int(x[1]) for x in rows[1:]} #idx 1: to skip header 

    return row_form 

def read_with_row_format(data_file, rform): 

    with open(data_file, 'r') as fd_data: 

     for row in fd_data.readlines(): 

      #Get the formatted output 
      #use .items() for Python 3.x 
      formatted_output = [row[k-1:k+v-1] for k, v in rform.iteritems()] 
      print formatted_output 

第一函數獲得「行格式」和第二函數應用於的行格式於每行的文件

用法中:

rform = get_row_format('lengths.csv') 
read_with_row_format('data.csv', rform) 

輸出:

['A', '1', '12', '34', '5', '6'] 
['B', '2', '12', '34', '5', '6'] 
['C', '3', '23', '45', '6', '7'] 
+1

請看下面的@Psidom答案,因爲它早些時候發佈,所以我的贊助人只有更多,但Psidom的答案更優雅。我將在這裏留給那些只想使用本機數據類型的人 –

1

由於您有每個字段的起始位置和長度,請使用它們。 這裏是代碼,以執行此。每條線都是依次進行的。每個字段是從開始列到相同位置加上字段長度的切片。

我將轉換留給您。

data = [ 
    "A1 1234 56", 
    "B2 1234 56", 
    "C3 2345167" 
] 

table = [ 
    [1, 1], 
    [2, 1], 
    [3, 1], 
    [4, 2], 
    [6, 2], 
    [8, 2], 
    [10, 1] 
] 

for line in data: 
    fields = [line[(table[col][0]-1) : (table[col][0]+table[col][1]-1)] for col in range(len(table))] 
    print fields