Поиск заголовка в текстовом файле Python Pandas

Итак, есть несколько вот таких файлов, в которые каждый день пишется SMART дисков.

Пример содержимого

23.04.2022 15:57:51,76 
smartctl 7.0 2018-12-30 r4883 [i686-w64-mingw32-w10-b19041(64)] (sf-7.0-1)
Copyright (C) 2002-18, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF READ SMART DATA SECTION ===
SMART Attributes Data Structure revision number: 1
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  1 Raw_Read_Error_Rate     0x002f   100   100   050    Pre-fail  Always       -       0
  5 Reallocate_NAND_Blk_Cnt 0x0032   100   100   010    Old_age   Always       -       0
  9 Power_On_Hours          0x0032   100   100   050    Old_age   Always       -       2544
 12 Power_Cycle_Count       0x0032   100   100   050    Old_age   Always       -       686
171 Program_Fail_Count      0x0032   100   100   050    Old_age   Always       -       0
172 Erase_Fail_Count        0x0032   100   100   050    Old_age   Always       -       0
173 Ave_Block-Erase_Count   0x0032   100   100   050    Old_age   Always       -       11
174 Unexpect_Power_Loss_Ct  0x0032   100   100   050    Old_age   Always       -       24
180 Unused_Reserve_NAND_Blk 0x0032   100   100   050    Old_age   Always       -       100
183 SATA_Interfac_Downshift 0x0032   100   100   050    Old_age   Always       -       0
184 Error_Correction_Count  0x0032   100   100   050    Old_age   Always       -       0
187 Reported_Uncorrect      0x0032   100   100   050    Old_age   Always       -       0
194 Temperature_Celsius     0x0022   066   039   050    Old_age   Always   In_the_past 34 (Min/Max 28/61)
196 Reallocated_Event_Count 0x0032   100   100   050    Old_age   Always       -       0
197 Current_Pending_Sector  0x0032   100   100   050    Old_age   Always       -       0
198 Offline_Uncorrectable   0x0030   100   100   050    Old_age   Offline      -       0
199 UDMA_CRC_Error_Count    0x0032   100   100   050    Old_age   Always       -       63
202 Percent_Lifetime_Remain 0x0030   100   100   001    Old_age   Offline      -       100
206 Write_Error_Rate        0x002e   100   100   050    Old_age   Always       -       0
210 Success_RAIN_Recov_Cnt  0x0032   100   100   050    Old_age   Always       -       0
246 Total_Host_Sector_Write 0x0032   100   100   050    Old_age   Always       -       853112131
247 Host_Program_Page_Count 0x0032   100   100   050    Old_age   Always       -       26659754
248 FTL_Program_Page_Count  0x0032   100   100   050    Old_age   Always       -       13031424

Пытаюсь строить графики по каждому параметру. Пока получается только так:

import pandas as pd
import matplotlib.pyplot as plt

df=pd.read_csv(
    'CT120BX500SSD1.txt',
    sep='\s+',
    header=6,
    error_bad_lines=False)

id246 = df[df['ID#'] == '246']
id246['RAW_VALUE'] = id246['RAW_VALUE'].astype(int)

plt.plot(id246['RAW_VALUE'])
plt.show()

А дальше вопросы, которые мне не под силу решить. И вот один из них:

  • Во всех файлах в начале файла присутствует служебная информация по диску, и из-за этого начало данных начинается с разных строк (в данном случае начинается с седьмой строки, поэтому при импорте приходится ставить header=6 а в других файлах другие значения этого параметра). Как, и можно ли в принципе, сделать универсальный способ, который позволял бы брать заголовок сразу из нужной строки?

Ответы (2 шт):

Автор решения: strawdog

Если у вас отчеты однотипны, и отличаются только количеством строк в заголовках, а параметр с температурой присутствует в каждом отчете, то можете сделать так:

import pandas as pd
import re

fname = "CT120BX500SSD1.txt"
with open(fname, 'r') as fh:
    file = fh.readlines()
    rawdata = [re.sub(r"\s+",',', y.strip(), count=9) for y in file if re.match(r"\s*?\d+\s",y)]
    columns = ["ID", "ATTRIBUTE_NAME", "FLAG", "VALUE", "WORST", "THRESH", "TYPE", "UPDATED", "WHEN_FAILED", "RAW_VALUE"]

df = pd.DataFrame([x.split(',') for x in rawdata], columns=columns)```
→ Ссылка
Автор решения: SergFSM

ваш файл можно прочитать еще так:

import pandas as pd

with open('CT120BX500SSD1.txt') as f:
    while not (l:=f.readline()).startswith('ID'): continue
    col = l.strip().split()
    rows = [r.strip().split(maxsplit=9) for r in f.readlines()]
df = pd.DataFrame(rows,columns=col)

>>> df
'''
    ID#           ATTRIBUTE_NAME    FLAG VALUE WORST THRESH      TYPE  UPDATED  WHEN_FAILED           RAW_VALUE
0     1      Raw_Read_Error_Rate  0x002f   100   100    050  Pre-fail   Always            -                   0
1     5  Reallocate_NAND_Blk_Cnt  0x0032   100   100    010   Old_age   Always            -                   0
2     9           Power_On_Hours  0x0032   100   100    050   Old_age   Always            -                2544
3    12        Power_Cycle_Count  0x0032   100   100    050   Old_age   Always            -                 686
4   171       Program_Fail_Count  0x0032   100   100    050   Old_age   Always            -                   0
5   172         Erase_Fail_Count  0x0032   100   100    050   Old_age   Always            -                   0
6   173    Ave_Block-Erase_Count  0x0032   100   100    050   Old_age   Always            -                  11
7   174   Unexpect_Power_Loss_Ct  0x0032   100   100    050   Old_age   Always            -                  24
8   180  Unused_Reserve_NAND_Blk  0x0032   100   100    050   Old_age   Always            -                 100
9   183  SATA_Interfac_Downshift  0x0032   100   100    050   Old_age   Always            -                   0
10  184   Error_Correction_Count  0x0032   100   100    050   Old_age   Always            -                   0
11  187       Reported_Uncorrect  0x0032   100   100    050   Old_age   Always            -                   0
12  194      Temperature_Celsius  0x0022   066   039    050   Old_age   Always  In_the_past  34 (Min/Max 28/61)
13  196  Reallocated_Event_Count  0x0032   100   100    050   Old_age   Always            -                   0
14  197   Current_Pending_Sector  0x0032   100   100    050   Old_age   Always            -                   0
15  198    Offline_Uncorrectable  0x0030   100   100    050   Old_age  Offline            -                   0
16  199     UDMA_CRC_Error_Count  0x0032   100   100    050   Old_age   Always            -                  63
17  202  Percent_Lifetime_Remain  0x0030   100   100    001   Old_age  Offline            -                 100
18  206         Write_Error_Rate  0x002e   100   100    050   Old_age   Always            -                   0
19  210   Success_RAIN_Recov_Cnt  0x0032   100   100    050   Old_age   Always            -                   0
20  246  Total_Host_Sector_Write  0x0032   100   100    050   Old_age   Always            -           853112131
21  247  Host_Program_Page_Count  0x0032   100   100    050   Old_age   Always            -            26659754
22  248   FTL_Program_Page_Count  0x0032   100   100    050   Old_age   Always            -            13031424
1
'''

P.S. это не будет работать если служебные строки тоже могут начинаться с 'ID'

→ Ссылка