2016-04-21 14 views
1

Hallo Ich habe ein Netzwerk in einem bestimmten Format, d. H. .gdf. Dies ist jedoch eine Textdatei in dem folgende FormatPython: wie zu analysieren und Inhalt zu einer Textdatei hinzufügen

network: 
nodedef>name VARCHAR,label VARCHAR 
0,' 0 ' 
1,' 1 ' 
2,' 2 ' 
edgedef>node1 VARCHAR,node2 VARCHAR,weight DOUBLE 
0,1,0.2 
0,2,0.2 
0,3,0.2 
0,4,0.333333 

wo der erste Teil an den Kanten zu Knoten und den zweiten Teil bezieht.

Ich möchte Feature hinzufügen, um die Datei zu lesen und ein Feature zu den Knoten hinzuzufügen und das Rück folgendes:

network: 
nodedef>name VARCHAR,label VARCHAR, att1 VARCHAR 
0,' 0 ', 'Paul' 
1,' 1 ', 'Jack' 
2,' 2 ', 'John' 
edgedef>node1 VARCHAR,node2 VARCHAR,weight DOUBLE 
0,1,0.2 
0,2,0.2 
0,3,0.2 
0,4,0.333333 
+4

Was haben Sie bisher versucht und welchen Fehler bekommen Sie? – Francesco

+0

Ich habe versucht, es als Pandas 'Datenframe' zu ​​lesen und eine neue Spalte hinzuzufügen, aber ich denke, es ist die richtige Lösung. – emax

+0

Sie geht zu weit, lesen Sie es Zeile für Zeile, behandeln als normale Datei, außer der ersten Zeile, wenn es> enthält, dann folgt eine neue Kategorie (in Diktat beibehalten, deren Wert eine Liste von Listen/Zeilen sind, verwenden (um die gewünschten Informationen zu erfassen) und eine Liste. append würde für Sie arbeiten –

Antwort

0

Hier einige Code, der die erste Hälfte der tut, was Sie gefragt. Es wird die .GDF Datei analysieren und Ihnen die Informationen zur Verfügung stellen. Das Hinzufügen und Schreiben von Attributen bleibt dem Leser als Übung überlassen.

import ast 
import collections 
import re 


def main(): 
    parser = GDFParser() 
    with open('network.gdf') as file: 
     parser.read(file) 
    print(*parser.data, sep='\n') 


def pivot(iterable): 
    columns = [] 
    for row in iterable: 
     columns.extend([] for _ in range(len(row) - len(columns))) 
     for column, cell in zip(columns, row): 
      column.append(cell) 
    return columns 


class GDFParser: 

    HEADER = re.compile('\w+:') 
    DEF = re.compile('\w+>\w+ (?:DOUBLE|VARCHAR)(?:,\w+ (?:DOUBLE|VARCHAR))*') 
    CAST = dict(DOUBLE=float, VARCHAR=str) 

    def __init__(self): 
     self.__header = None 
     self.__type = [] 
     self.__data = [] 

    @property 
    def header(self): 
     return self.__header 

    @property 
    def data(self): 
     return tuple(self.__data) 

    def read(self, file): 
     for line in file: 
      self.__read_line(line.strip()) 

    def __read_line(self, line): 
     if self.HEADER.fullmatch(line): 
      self.__process_header(line) 
     elif self.DEF.fullmatch(line): 
      self.__process_def(line) 
     else: 
      self.__process_data(line) 

    def __process_header(self, line): 
     if self.header: 
      raise ValueError('header was previously set') 
     self.__header = line[:-1] 

    def __process_def(self, line): 
     name, fields = line.split('>') 
     columns, casts = pivot(field.split() for field in fields.split(',')) 
     self.__type.append((collections.namedtuple(name, columns), 
          tuple(map(self.CAST.__getitem__, casts)))) 

    def __process_data(self, line): 
     if not self.__type: 
      raise ValueError('a definition must come before its data') 
     kind, casts = self.__type[-1] 
     self.__data.append(kind(*(cast(item) for cast, item in 
            zip(casts, ast.literal_eval(line))))) 


if __name__ == '__main__': 
    main() 
Verwandte Themen