2017-06-08 2 views
0

/tldr Suchen nach einer großen Menge von Dateinamen, die eine Verkettung von zwei Namen (Container + Kind) für die ursprünglichen zwei Namen, wo Nomenklatur ist inkonsistent. Python Bibliothek Vorschläge oder andere Anleitung geschätzt.Verwenden von Python zum Analysieren einer großen Menge von Dateinamen aus inkonsistenten Objektnamen

Ich bin auf der Suche nach einer Möglichkeit, Strings für Informationen zu analysieren, wo die Nomenklatur und die Formatierung von Informationen innerhalb dieser Strings wahrscheinlich bis zu einem gewissen Grad inkonsistent sein werden.

Hintergrund Branche: Automation steuert

Problem zu lösen:
Zeitreihendaten von einem Automatisierungssystem mit einem einzelnen Datenpunkt exportiert wird auf eine einzige CSV-Datei gespeichert werden. (Beispiel: Wenn das Kontrollsystem war ein Umweltkontrollsystem des Punkt könnte die gemessene Temperatur eines Raumes in 15 Minuten-Intervallen entnommen werden.) Es ist möglich, eine Umgebung zu haben, wo es ein paar Dutzende Punkte, die in CSV-Dateien oder mehr exportieren Tausend Punkte, die in CSV-Dateien exportiert werden. Die Struktur, die die Punkte normalerweise gespeichert sind, in ist wie folgt: Punkte sind in einer Steuereinheit enthalten ist, unter einem Controller-Management-System integriert sind, und gelegentlich Managementsysteme können in ein anderes Verwaltungssystem integriert werden. Die resultierende Struktur ist ein einfacher hierarchischer Baum.

Die den CSV-Dateien zugeordneten Dateinamen werden wie folgt aus der Pfadstruktur jedes Punkts zusammengesetzt: Verzeichnisse werden für die Verwaltungssysteme erstellt (bei Bedarf verschachtelt) und unter diesen Verzeichnissen befinden sich die CSV-Dateien, deren Dateiname eine Verkettung von der Controller-Name und der Punktname.

Ich habe ein Python-Skript geschrieben, das einen monatlichen Export der CSV-Dateien (derzeit etwa 5500 davon [wächst]) in einen strukturierten Datenspeicher und ein anderes, Tabellenkalkulationen für andere zu überarbeiten verarbeitet. Zurzeit verwende ich einige wirklich hässliche reguläre Ausdrücke und sogar hässlicher string.find() s mit einer Liste von statischen String - Werten, die ich manuell eingegeben habe, um Kontroll - Namen und Punktnamen für jede Datei auszufiltern, damit sie in die eingefügt werden können strukturierter Datenspeicher

Leider, wie oben erwähnt, wird die Nomenklatur in diesen Umgebungen verwendet werden, sind selten konsistent. Punktnamen sind sehr unterschiedlich. Der Punkt oben genannten könnte als RAUM, RM_T, RMT, ROOM-T, ZN_T, ZNT, RMT oder mehrere andere Möglichkeiten bekannt sein. Dies gilt für fast jeden Punkt in einem Controller. Controller-Namen sind auch etwas inkonsistent, wo sie nach dem Typ des Geräts, das sie steuern, dem geografischen Standort des Geräts oder sogar einer Asset-Nummer, die dem Gerät zugeordnet ist, benannt werden können.

Ich würde sehr gerne aus dem Geschäft der Hand schreiben reguläre Ausdrücke zu Parsing Dateinamen jedes Mal, wenn ein neuer Ort hinzugefügt wird. Ich mag Code schreiben, die in Dateinamen lesen und suchen nach Mustern in den Dateinamen und machen dann eine Empfehlung für das Parsen der Steuerung und Punktnamen aus jedem Dateinamen. Ich habe bereits eine Schnittstelle, wo ich jedem Punktobjekt Controller-Namen und Punktnamen von Hand zuweisen kann. Wenn es Fehler bei der Syntaxanalyse gibt, kann ich die Ergebnisse modifizieren. Im Idealfall würden die von den vorhandenen Objekten erzeugten Muster die vorgeschlagenen Namen neuer zu analysierender Dateien beeinflussen.

Einige Beispiele für Dateinamen sind wie folgt: UNIT1254_SAT.csv, UNIT1254_RMT.csv, UNIT1254_fil.csv, AHU_5311_CLG_O.csv, QE239-01_DISCH_STPT.csv, HX_E2_CHW_Return.csv, Plant_RM221_CHW_Sys_Enable.csv, TU_E7_Actual Clg Setpoint.csv, 1725_ROOMTEMP .csv, 1725_DA_T.csv, 1725_RA_T.csv

Die Reihenfolge ist immer konsistent, wenn es sich um eine Verkettung des Controllernamens und des Punktnamens handelt.Es wird höchstwahrscheinlich ein konsistentes Zeichen geben, das den Controller-Namen vom Punktnamen trennt (normalerweise ein Unterstrich, aber gelegentlich ein Bindestrich oder ein anderes Zeichen).

Hat jemand irgendwelche Empfehlungen, wie man mit dem Parsen dieser Dateinamen beginnt? ? Ich habe ein paar Ideen durchdiskutiert, behalte sie aber bevor ich sie ausprobiere, bevor ich sie ausprobiere, weil ich immer das Potenzial für Performance-Probleme entdecke oder Fehlerpunkte identifiziere. Der Rest meines Codes funktioniert so, wie ich es brauche. Ich habe einfach keine effiziente oder nützliche Methode gefunden, die richtigen Namen aus dem Dateinamen zu ziehen. Leider ist es keine Option, die Namen auf der Seite des Kontrollsystems zu ändern, um konsistent zu sein.

+0

Hallo. Ich habe dein Problem nur grob verstanden. Ich habe den Eindruck, dass Sie den Namen des Steuerelements von dem in einem Dateinamen vorhandenen Punktnamen trennen möchten, ohne vorher wissen zu müssen, was die Namen sein können, und außerdem nicht genau zu wissen, wo sich das Trennzeichen im Dateinamen befinden kann nur ein (1 Containername) oder zwei (2 Containernamen). Sie schreiben jedoch reguläre Ausdrücke, verwenden str.find() und statische Zeichenfolgenwerte. Sie haben also am Anfang einige Informationen. Was sind diese Informationen? Versuchen Sie bitte mehr zu erklären. – eyquem

+0

Es gibt einige Ähnlichkeiten zwischen ROOMTEMP, RM-T, RM-T, ROOM-T, RMT; aber nicht mit ZN_T und ZNT, abgesehen vom T! Es gibt die Möglichkeit, die Ähnlichkeit zwischen den 5 ersten, aber nicht mit den 2 letzten zu erkennen. – eyquem

+0

Es scheint, dass Sie nur die Dateinamen kennen, nicht die hierarchische Struktur, die die Struktur von Controllern und Managementsystemen darstellt. Ist es richtig ? – eyquem

Antwort

0

Ich weiß nicht, ob der folgende Code Ihnen helfen wird, aber ich hoffe, es wird Ihnen zumindest eine Idee geben.

Bedenkt man, dass ein Dateiname als "QE239-01_STPT_1725_ROOMTEMP_DA" folgende Namen enthalten kann
'QE239-01'
'QE239-01_STPT'
'QE239-01_STPT_1725'
'QE239-01_STPT_1725_ROOMTEMP'
‚QE239 -01_STPT_1725_ROOMTEMP_DA '
'STPT'
'STPT_1725'
'STPT_1725_ROOMTEMP'
'STPT_1725_ROOMTEMP_DA'
' 1725'
'1725_ROOMTEMP'
'1725_ROOMTEMP_DA'
'RAUM'
'ROOMTEMP_DA'
'DA'
wie möglich Elemente (Containername oder Punktnamen) aus dem Dateinamen, I die Funktion definiert treat() um diese Liste vom Namen zurückzugeben.

Dann behandelt der Code alle Dateinamen, um alle möglichen Elemente von Dateinamen zu finden. Die Funktion basiert auf der Idee, dass in dem gewählten Beispiel das Element ROOMTEMP dem Element STPT nicht folgen kann, da STPT_ROOMTEMP kein möglicher Containername in dieser Beispielzeichenfolge ist, da zwischen diesen beiden Elementen 1725 liegt.

Und dann, mit Hilfe einer Funktion in difflib Modul, versuche ich Elemente zu unterscheiden, die einige Ähnlichkeit haben, um zu versuchen, Muster zu erkennen, unter denen mehrere Elemente von Namen gesammelt werden können.

Sie müssen mit dem Wert spielen, der als Argument an cutoff Parameter übergeben wird, um auszuwählen, was das Beste sein könnte, um interessante Ergebnisse für Sie zu geben.

Es ist bei weitem nicht gut, aber ich habe nicht alle Aspekte Ihres Problems verstanden.

s =\ 
"""UNIT1254_SAT 
UNIT1254_RMT 
UNIT1254_fil 
AHU_5311_CLG_O 
QE239-01_DISCH_STPT, 
HX_E2_CHW_Return 
Plant_RM221_CHW_Sys_Enable 
TU_E7_Actual Clg Setpoint 
1725_ROOMTEMP 
1725_DA_T 
1725_RA_T 
UNT147_ROOMTEMP 
TRU_EZ_RM_T 
HXX_V2_RM-T 
RHXX_V2_ROOM-T 
SIX8_ZN_T 
Plint_RP228_ZNT 
SOHO79_EZ_RMT""" 

li = s.split('\n') 
print(li) 
print('- - - - - - - - - - - - - - - - - ') 

import difflib 
from pprint import pprint 

def treat(name): 
    lu = name.split('_') 
    W = [] 
    while lu: 
     W.extend('_'.join(lu[0:x]) for x in range(1,len(lu)+1)) 
     lu.pop(0) 
    return W 

if 0: 
    q = "QE239-01_STPT_1725_ROOMTEMP_DA" 
    pprint(treat(q)) 
    print('==========================================') 

WALL = [] 
for t in li: 
    WALL.extend(treat(t)) 
pprint(WALL) 

for x in WALL: 
    j = set(difflib.get_close_matches(x, WALL, n=9000000, cutoff=0.7)) 
    if len(j)>1: 
     print(j,'\n') 
Verwandte Themen