2017-02-22 31 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=" ")

Но я не мог понять, как разделить.

Как я могу читать и разделять данные?

+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 здесь для демонстрационной цели. Но да, более строгий способ может объявить его как Юникод. Спасибо за указание. – 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