Извлечение информации между строками из файла и запись в CSV - PullRequest
0 голосов
/ 20 июня 2019

Я хотел бы извлечь некоторую информацию (между строками, например oldtime: ... oldtime!>) Из текстового файла и записать ее в файл CSV. Мой входной текстовый файл выглядит так:

=======================
oldtime:

 hours:1:hours!>

 minutes:12:minutes!> 

oldtime!>

newtime:

 hours:15:hours!>

 minutes:17:minutes!> 

newtime!>


oldtime:

 hours:11:hours!>

 minutes:22:minutes!> 

oldtime!>  


newtime:

 hours:5:hours!>

 minutes:17:minutes!> 

newtime!>  

==========================              

Я начал с этого, но не могу идти дальше.

with open(inputfile, 'r') as f, open(outputfile.cvs, 'a') as f1:
    f1.write("oldtime; newtime \n")
    for row in f:
        if "oldtime:" in str(row):
            temp = re.split(r'(@oldtime[\n\r]|[\n\r]@oldtime!>)', str(row))

            ???

        if "newtime:"  in str(row):
            temp = re.split(r'(@newtime[\n\r]|[\n\r]@newtime!>)', str(row))

Я хотел бы получить в качестве вывода CSV-файл, подобный этому

oldtime  newtime
01:12     15:17
11:22     05:17

Не могли бы вы мне помочь? Спасибо.

Ответы [ 3 ]

2 голосов
/ 20 июня 2019

Это один подход с использованием Regex и модуля csv.

Ex:

import re
import csv

with open(filename) as infile, open(filename_1, "w") as outfile:
    data = infile.read()
    hrs = re.findall(r"hours:(\d+):hours", data)       #Get all HRS
    mins = re.findall(r"minutes:(\d+):minutes", data)  #Get All Mins
    data = zip(hrs, mins)

    writer = csv.writer(outfile)                       #Write CSV
    writer.writerow(["oldtime", "newtime"])            #Header
    for m, n in zip(data[0::2], data[1::2]):         
        writer.writerow([":".join(m), ":".join(n)])    #Write OLD time & New Time
1 голос
/ 20 июня 2019

Другое решение, близкое к решению Ракеша, предполагая, что ваш файл всегда имеет одну и ту же структуру (старое время -> час -> мин -> новое время -> час -> мин ...).

  1. Извлечение все номера строки с формулой регулярного выражения: match = re.findall(r'\d+', str_file)

  2. Преобразуйте этот список, соединив hours и minutes: dates = [i+ ":" + j for i, j in zip(match[::2], match[1::2])]

  3. Создание dataframe с использованием модуля pandas

  4. Экспорт данных

Вот код:

# Import module
import pandas as pd

with open("../temp.txt", 'r') as f:
    # Read file as a string
    str_file = f.read()

    # Extract all numbers
    match = re.findall(r'\d+', str_file)
    print(match)
    # ['1', '12', '15', '17', '11', '22', '5', '17']

    # create dates
    dates = [i+ ":" + j for i, j in zip(match[::2], match[1::2])]
    print(dates)
    # ['1:12', '15:17', '11:22', '5:17']

    # create dataframe
    df = pd.DataFrame({"oldtime": dates[::2],
                        "newtime": dates[1::2]})
    print(df)
    #    oldtime  newtime
    # 0    1:12   15:17
    # 1   11:22    5:17

    # Export the data
    df.to_csv("output.csv", index= False)

enter image description here

РЕДАКТИРОВАТЬ 1: Предполагая, что блоки oldtime и newtime могут быть прокручены. Здесь я читаю строку файла в каждой строке и классифицирую oldtime и newtime в словаре. Есть много slice, но они работают над моим тестовым файлом.

# Import module
import pandas as pd

with open("../temp.txt", 'r') as f:
    # Read file as a string
    list_split = ["oldtime:", "newtime:"]
    dates = {"oldtime:": [], "newtime:": []}
    line = f.readline().rstrip('\n')

    while True:
        line = line.rstrip('\n')
        print([line])
        if line in list_split:
            key = line

            hours = f.readline().rstrip('\n').split(":")[1]
            minutes = f.readline().rstrip('\n').split(":")[1]

            dates[key].append(hours+':'+minutes)

        line = f.readline()
        if not line:
            break

    print(dates)
    # {'oldtime:': ['1:12', '11:22'], 'newtime:': ['15:17', '5:17']}

    # create dataframe
    df = pd.DataFrame({"oldtime": dates["oldtime:"],
                       "newtime": dates["newtime:"]})
    print(df)
    #    oldtime  newtime
    # 0    1:12   15:17
    # 1   11:22    5:17

    # Export the data
    df.to_csv("output.csv", index=False)

РЕДАКТИРОВАТЬ 2:

import pandas as pd

with open("../temp.txt", 'r') as f:
    # Read file as a string
    list_split = ["oldtime:", "newtime:"]
    dates = {"oldtime": [], "newtime": []}
    line = f.readline().rstrip('\n')

    while True:
        # Ignore blank lines
        if ("oldtime:" in line) or ("newtime:" in line):
            # Process new "oldtime" or "newtime" block

            # Class : either "oldtime" or "newtime"
            class_time = line.replace(" ", "").rstrip('\n')[:-1]

            # Default hour - minute values
            hours = "24"
            minutes = "60"

            # Read next line
            line = f.readline().rstrip('\n')

            # While block not ended 
            while class_time + "!>" not in line:
                # If hour in line: update hour
                if 'hour' in line:
                    hours = line.split(":")[1]
                # If minute in line: update minute
                elif 'minute' in line:
                    minutes = line.split(":")[1]

                # Read next line
                line = f.readline().rstrip('\n')
            # End block

            # Add block read to dictionary
            dates[class_time].append(hours+':'+minutes)

        # Read next line
        line = f.readline()
        # If end of file: exit
        if not line:
            break

    # create dataframe
    df = pd.DataFrame({"oldtime": dates["oldtime"],
                       "newtime": dates["newtime"]})

    # Export the data
    df.to_csv("output.csv", index=False)

Надеюсь, что справка!

0 голосов
/ 20 июня 2019

большой вопрос:).

Вот простое решение, которое я сделал, разграничив строку на символе ":", превратив числовые строки в целые числа, объединив их с:, а затем записав их в csv.

Вот код:

import csv
f = "data.txt"
with open('data.txt','r') as f:
    data = f.read()
data = data.split(sep=':')
nums = []
for i in data:
    try:
        nums.append(int(i))
    except ValueError:
        pass

times = []
for i in range(len(nums)):
    if i%2 ==0:
        times.append(str(nums[i]) + ":" + str(nums[i+1]))
num_rows = len(times)/2

with open('time_data.csv','w+',newline='') as f:
    writer = csv.writer(f)
    writer.writerow(['oldtime','newtime'])
    for i in range(len(times)):
        if i%2==0:
            writer.writerow([times[i],times[i+1]])

Прочитав ответ Ракеша, я написал следующее:

import re
import csv
list_i = ''
file_name = 'data.txt'
file_name1 = 'data_1.txt'
with open(file_name,'r') as f, open(file_name1,'w',newline='') as f1:
    data = f.read()
    list_1 = re.findall(r'hours:\d+:hours',data)
    list_2 = re.findall(r'minutes:\d+:minutes',data)
    for i in list_1:
        list_i += i  
    list_2_i = ''
    for i in list_2:
        list_2_i += i 
    list_1 = re.findall(r'\d+',list_i)
    list_2 = re.findall(r'\d+',list_2_i)
    data = []
    for i in range(len(list_1)):
        if i%2==0:
            data.append([str(list_1[i]) + ':' + str(list_2[i]),str(list_1[i+1]) + ':' + str(list_2[i+1])])
    writer = csv.writer(f1)
    writer.writerow(['oldtime','newtime'])
    for i in data:
        writer.writerow(i)

Также @Rakesh ваш код вернул ошибку: TypeError:'zip' объект не является подписным. Есть ли способ исправить это?:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...