2017-02-22 8 views
1

私は以下のようなテキストファイルを持っています。特定の状態でtxtを読む方法

A1 1234 56 
B2 1234 56 
C3 2345167 

私は開始位置と長さの表を持っています。 は、各要素が前の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=" ")

を試してみました。しかし、私は分割する方法を見つけ出すcouldntの。

データフレームの読み取りと分割を行うにはどうすればよいですか?

+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

あなたの答えは私のものよりもはるかに優れています:) 'TypeError'を防ぐために' StringIO'のためにUnicode文字列を使う必要があるかもしれないと言えますか? –

+0

@KJPhanありがとう!通常これで問題は発生しません。ここのStringIOはデモンストレーションの目的で使用しています。しかし、ええ、より厳密な方法は、Unicodeとして宣言しているかもしれません。指摘してくれてありがとう。 – Psidom

2

コメントに記載されているとおり、これはCSV形式ではないため、回避策を用意する必要がありました。

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'] 

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 

最初の機能は、「行フォーマット」と第2の機能を取得し、ファイル

使用の各行に、その行のフォーマットを適用します

+1

下記の@Psidomの回答を見てください。私は早く投稿されたので、より多くのupvotesを持っていますが、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 
関連する問題