Извлечение текстовых данных в значимую таблицу для анализа с использованием Python (или R) - PullRequest
0 голосов
/ 20 апреля 2019

Я работаю над инженерным проектом, в котором я использую данные о производительности машины из архивов. Аппарат создает один набор данных примерно каждые 5 секунд, и эти данные затем становятся доступными по дате в количестве файлов .txt, каждый файл содержит данные в следующем формате. Данные, показанные ниже, взяты из файла 2013_04_17.txt, в котором содержатся все данные о производительности за эту конкретную дату.

2013-04-27 00:00:05.011
V_1 100  V_2 26695  V_3 33197  V_4 c681  V_5  29532
V_6 4600  V_7 4606  V_8 4f55  V_9 5a  V_10  8063  V_11  4300  V_12  4700
V_13 4504  V_14 4400  V_15 4202  V_16 255  V_17  4300  V_18  91  V_19  6f
V_20 300  V_21 14784 
V_22 5.085  V_23 7.840  V_24 -8.061  V_25 36.961

2013-04-27 00:00:10.163
V_1 100  V_2 26695  V_3 33199  V_4 c681  V_5  29872
V_6 4600  V_7 4606  V_8 4f55  V_9 5a  V_10  8063  V_11  4300  V_12  4700
V_13 4504  V_14 4400  V_15 4202  V_16 255  V_17  4300  V_18  91  V_19  6f
V_20 300  V_21 14790 
V_22 5.085  V_23 7.840  V_24 -8.061  V_25 37.961

..........

Мне нужно просмотреть эти данные в табличном формате или в формате CSV, чтобы иметь возможность создавать графики производительности и обнаруживать любые аномалии. Тем не менее, у меня недостаточно опыта программирования на Python, чтобы можно было проанализировать этот текстовый файл.

Я искал панды и регулярные выражения для некоторых идей, но не смог достичь желаемого результата, и я надеюсь получить данные в табличной форме или файл CSV с заголовком в качестве переменных Date, Time, V_1, V_2, V_3 и т. Д. И последующие строки как все значения, полученные каждые 5 с.

Ответы [ 5 ]

0 голосов
/ 20 апреля 2019

попробуй мой простой код, я использовал панд

import pandas as pd

with open('2013_04_17.txt', 'r') as f:
    large_list = [word for line in f for word in line.split() if 'V_' not in word]
    print(large_list)
    col_titles = ('date','time','v1','v2','vN','vN','vN','vN','vN','vN','vN','vN'
                  ,'vN','vN','vN','vN','vN','vN','vN','vN','vN','vN','vN','vN','vN','vN','vN')
    data = pd.np.array(large_list).reshape((len(large_list) // 27, 27))
    pd.DataFrame(data, columns=col_titles).to_csv("output3.csv", index=False) 
0 голосов
/ 20 апреля 2019

В R, и это будет очень специфично для вашего случая, вы можете попробовать выбросить все файлы .txt в новую папку, например, назвать ее date_data. Предполагая, что все файлы в одном и том же формате, попробуйте запустить это.

library(purrr)
library(tidyverse)

setwd(./date_data)
odd_file_reader <- function(x){
  as.data.frame(matrix(scan(x, what="character", sep=NULL), ncol = 52, byrow = TRUE)[,-seq(3,51,2)])
}

binded_data <- tibble(filenames = list.files()) %>%
  mutate(yearly_sat = map(filenames, odd_file_reader)) %>%
  unnest()
0 голосов
/ 20 апреля 2019

Вы можете начать с чтения токенов по одному из файла:

with open('2013_04_17.txt') as infile:
    for line in infile:
        for token in line.split():
            print(token)

После этого вам просто нужно создать конечный автомат, чтобы запомнить, в каком разделе вы находитесь, и обработать каждый раздел, когда найдете его конец:

def process_record(timestamp, values):
    """print CSV format"""
    print(','.join([timestamp] + values))

with open('t.txt') as infile:
    timestamp = None
    values = []
    for line in infile:
        line = line.strip()
        if timestamp is None:
            timestamp = line
        elif not line: # blank line is separator
            process_record(timestamp, values)
            timestamp = None
            values = []
        else:
            values.extend(line.split()[1::2])
    if timestamp is not None: # process last record, no separator after it
        process_record(timestamp, values)

Это дает вам выход CSV:

2013-04-27 00:00:05.011,100,26695,33197,c681,29532,4600,4606,4f55,5a,8063,4300,4700,4504,4400,4202,255,4300,91,6f,300,14784,5.085,7.840,-8.061,36.961
2013-04-27 00:00:10.163,100,26695,33199,c681,29872,4600,4606,4f55,5a,8063,4300,4700,4504,4400,4202,255,4300,91,6f,300,14790,5.085,7.840,-8.061,37.961
0 голосов
/ 20 апреля 2019

Есть намного более простой способ.Предполагая, что эти данные появляются в столбцах в файле .txt (т. Е. Данные имеют формат Fixed-Width ), вы можете использовать функцию pandas pandas.read_fwf () и передавать кортежи, содержащие экстентыполя фиксированной ширины каждой строки.

import pandas

colspecs = [(0,10), (11, 23), (28,31), (37, 42), (48, 54), (59, 63), (70, 75), ...]
data = pandas.read_fwf(TXT_PATH, colspecs = colspecs, header=None)
data.columns = ['date', 'time', 'V_1', 'V_2', 'V_3', 'V_4', 'V_5', ...]
print(data)

         date          time  V_1    V_2    V_3   V_4    V_5
0  2013-04-27  00:00:05.011  100  26695  33197  c681  29532
1  2013-04-27  00:00:10.163  100  26695  33199  c681  29872

И оттуда вы можете сохранить эти отформатированные данные в файл с помощью команды

data.to_csv('filename.csv', index=False)
0 голосов
/ 20 апреля 2019

Редактировать : Вы можете достичь тех же результатов без регулярного выражения следующим образом: обратите внимание, мы предполагаем, что формат файла все время один и тот же, поэтому мы ожидаем дату и время в начале файла

# reading data from a file for example log.txt
with open('log.txt', 'r') as f:
    data = f.read()

data = string.split()
v_readings = dict()
v_readings['date'] = data.pop(0)
v_readings['time' ]= data.pop(0)

i=0
while i < len(data):
    v_readings[data[i]] = data[i+1]
    i += 2

экспорт в CSV-файл:

csv = '\n'
csv += ','.join(v_readings.keys())
csv += '\n'
csv += ','.join(v_readings.values())

print(csv)
with open('out.csv', 'w') as f:
    f.write(csv)

выход:

date,time,V_1,V_2,V_3,V_4,V_5,V_6,V_7,V_8,V_9,V_10,V_11,V_12,V_13,V_14,V_15,V_16,V_17,V_18,V_19,V_20,V_21,V_22,V_23,V_24,V_25
2013-04-27,00:00:05.011,100,26695,33197,c681,29532,4600,4606,4f55,5a,8063,4300,4700,4504,4400,4202,255,4300,91,6f,300,14784,5.085,7.840,-8.061,36.961

с регулярным выражением: Вот как вы извлекаете эти данные, используя регулярные выражения в переменных и словарь в Python

это отправная точка, и тогда вы можете делать с ними все, что захотите.

import re 

string = """
2013-04-27 00:00:05.011 V_1 100 V_2 26695 V_3 33197 V_4 c681 V_5 29532 V_6 4600 V_7 4606 V_8 4f55 V_9 5a V_10 8063 V_11 4300 V_12 4700 V_13 4504 V_14 4400 V_15 4202 V_16 255 V_17 4300 V_18 91 V_19 6f V_20 300 V_21 14784 V_22 5.085 V_23 7.840 V_24 -8.061 V_25 36.961
"""
# extract date 
match = re.search(r'\d{4}-\d\d-\d\d', string)
my_date = match.group()

# extract time
match = re.search(r'\d\d:\d\d:\d\d\.\d+', string)
my_time = match.group()

#getting V's into a dictionary
match = re.findall(r'V_\d+ \d+', string)
v_readings = dict()
for item in match:
    k, v = item.split()
    v_readings[k] = v

# print output
print(my_date)
print(my_time)
print(v_readings)

выход:

2013-04-27
00:00:05.011
{'V_1': '100', 'V_2': '26695', 'V_3': '33197', 'V_5': '29532', 'V_6': '4600', 'V_7': '4606', 'V_8': '4', 'V_9': '5', 'V_10': '8063', 'V_11': '4300', 'V_12': '4700', 'V_13': '4504', 'V_14': '4400', 'V_15': '4202', 'V_16': '255', 'V_17': '4300', 'V_18': '91', 'V_19': '6', 'V_20': '300', 'V_21': '14784', 'V_22': '5', 'V_23': '7', 'V_25': '36'}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...