Seite 2 von 2

Re: CSV auslesen

Verfasst: Montag 30. Januar 2023, 15:42
von Feedback1000
Ahhhhh. Danke, fürs Drauf-Stupsen.
Macht das so mehr Sinn?

Code: Alles auswählen

from pprint import pprint

classifications = {
    'PL': [
        {
            'Atttributes': [
                {
                    'AT-Default': '',
                    'AT-Name': '',
                    'Ausrichtung': '',
                    # ...
                },
                # ...
            ],
            'Bemerkung': '',
            'Beschreibung': '',
            'Blockname': '',
            # ...
        },
        {
            'Atttributes': [
                {
                    'AT-Default': '',
                    'AT-Name': '',
                    'Ausrichtung': '',
                    # ...
                },
                {
                    'AT-Default': '',
                    'AT-Name': '',
                    'Ausrichtung': '',
                    # ...
                },
                # ...
            ],
            'Bemerkung': '',
            'Beschreibung': '',
            'Blockname': '',
            # ...
        }
    ],
    'PT': [
        {
            'Atttributes': [
                {
                    'AT-Default': '',
                    'AT-Name': '',
                    'Ausrichtung': '',
                    # ...
                },
                {
                    'AT-Default': '',
                    'AT-Name': '',
                    'Ausrichtung': '',
                    # ...
                },
                # ...
            ],
            'Bemerkung': '',
            'Beschreibung': '',
            'Blockname': '',
            # ...
        },
        {
            'Atttributes': [
                {
                    'AT-Default': '',
                    'AT-Name': '',
                    'Ausrichtung': '',
                    # ...
                },
                {
                    'AT-Default': '',
                    'AT-Name': '',
                    'Ausrichtung': '',
                    # ...
                },
                {
                    'AT-Default': '',
                    'AT-Name': '',
                    'Ausrichtung': '',
                    # ...
                },
                # ...
            ],
            'Bemerkung': '',
            'Beschreibung': '',
            'Blockname': '',
            # ...
        }
    ]
}

# Anmerkung: "..." steht für die fehlenden keys() in CLASSIFICATION_OBJECT_KEYS bzw. CLASSIFICATION_ATTRIBUTE_KEYS
pprint(classifications)

Re: CSV auslesen

Verfasst: Montag 30. Januar 2023, 16:10
von sparrow
Ich sage mal: grundsätzlich ja. Es kommt auch ein bisschen darauf an, was du hinterher damit machen willst.

Re: CSV auslesen

Verfasst: Montag 30. Januar 2023, 16:15
von __deets__
Ich sehe nicht, dass das mehr Sinn macht. Jetzt sind es Leerstrings. Wozu? Was sollen die erreichen? Wenn du einfach nur eine Liste von Attributnamen haben willst dann nimm eine Liste von Attributnamen.

Re: CSV auslesen

Verfasst: Montag 30. Januar 2023, 16:23
von Feedback1000
Naja, Leerstrings sind es nicht zwangsläufig, es hängt halt von den Daten in der CSV ab...
Ja, in den Beispieldaten der CSV die ich hochgelanden habe sind zwar viele Felder leer, aber wie gesagt weis ich noch nicht hundert Prozent welche Daten der AT-Zeile ich final brauche, deshalb will ich erst einmal alles "importieren".
Ferner habe ich etwas geändert, hat aber nichts mit der gerade geschriebenen Argumentation zu tun.

Code: Alles auswählen

CLASSIFICATION_OBJECT_KEYS = (
    'Objektart', 'Messcode', 'Bemerkung', 'Objekttyp', 'Beschreibung', 'Blockname', 'Layer', 'Kurzcode', 'Gruppe')
CLASSIFICATION_ATTRIBUTE_KEYS = (
    'Wert-ID', 'Wert-Spalte', 'Wert-Pos', 'Wert-Necessary', 'Wert-UebTab', 'Wert-Faktor', 'AT-Name', 'AT-Default',
    'Ausrichtung', 'SY-Art', 'SY-InsertMode', 'XSize', 'YSize', 'XSizeMin', 'XSizeMax', 'YSizeMin', 'YSizeMax',
    'XSize-ID', 'XSize-Pos', 'YSize-ID', 'YSize-Pos', 'SY-ZusObj', 'SY-EinsetzPkt', 'SY-RiCode', 'PosRechts', 'PosHoch',
    'Massband-Pos')

Re: CSV auslesen

Verfasst: Montag 30. Januar 2023, 17:42
von Feedback1000
Habe noch einmal getestet...sollte doch dann soweit passen...abgesehen von den wichtigen Attributes, oder kann man da noch etwas optimieren?!

Code: Alles auswählen

import csv
from collections import defaultdict
from pathlib import Path
from pprint import pprint

CLASSIFICATION_IDENTIFIER = (
    'PT',  # Punkte
    'SY',  # Symbole und gerichtete Punkte
    'PL',  # Linienzüge
    'SG',  # Gruppierte Linien
    'TX',  # Texte
    'FL',  # Flächen
)

ATTRIBUTE_IDENTIFIER = 'AT'  # Attribute zu einem Objekt
DELIMITER_CSV = ';'

CLASSIFICATION_OBJECT_KEYS = (
    'Objektart', 'Messcode', 'Bemerkung', 'Objekttyp', 'Beschreibung', 'Blockname', 'Layer', 'Kurzcode', 'Gruppe')
CLASSIFICATION_ATTRIBUTE_KEYS = (
    'Wert-ID', 'Wert-Spalte', 'Wert-Pos', 'Wert-Necessary', 'Wert-UebTab', 'Wert-Faktor', 'AT-Name', 'AT-Default',
    'Ausrichtung', 'SY-Art', 'SY-InsertMode', 'XSize', 'YSize', 'XSizeMin', 'XSizeMax', 'YSizeMin', 'YSizeMax',
    'XSize-ID', 'XSize-Pos', 'YSize-ID', 'YSize-Pos', 'SY-ZusObj', 'SY-EinsetzPkt', 'SY-RiCode', 'PosRechts', 'PosHoch',
    'Massband-Pos')

DATA_DIRECTORY = Path(
    r'C:/ProgramData/rmDATA/Shared/CodeGrafik')


def load_classification(filepath):
    classifications = defaultdict(list)
    with open(filepath) as csvdatei:
        reader = csv.DictReader(csvdatei, delimiter=DELIMITER_CSV)
        for line in reader:
            if line['Objektart'] in CLASSIFICATION_IDENTIFIER:
                needed_keys = {}
                for key, value in line.items():
                    if key in CLASSIFICATION_OBJECT_KEYS:
                        needed_keys.update({key: value})
                needed_keys.update({'Attributes': None})
                classifications[line['Objektart']].append(needed_keys)
    return classifications


def main():
    classifications = load_classification(
        DATA_DIRECTORY / 'VDLF.csv')
    # print(f'Anzahl Objekte: {len(classifications)}')
    # print(classifications.keys())
    for o in classifications:
        print(f'{o}: {len(classifications[o])}')
    # pprint(classifications)


if __name__ == '__main__':
    main()

Re: CSV auslesen

Verfasst: Montag 30. Januar 2023, 17:58
von sparrow
Was sind needed_keys?
Gib Dingen verständliche Namen. Das sind keine "benötigten Schlüssel", dass ist eine classification.

Warum ist Attributes None? Attributes soll doch eine Liste sein, in die die Attribute kommen.

Man setzt keine Schlüssel mit Update man setzt Schlüssel mit:

Code: Alles auswählen

x[key] = value
wobei x in diesem Fall der Name ist, an den das dict gebunden wurde.

Re: CSV auslesen

Verfasst: Montag 30. Januar 2023, 20:24
von __deets__
Feedback1000 hat geschrieben: Montag 30. Januar 2023, 16:23 Naja, Leerstrings sind es nicht zwangsläufig, es hängt halt von den Daten in der CSV ab...
Ah, mein Fehler - ich habe das irgendwie eher fuer ein Schema gehalten. Dann ist es natuerlich sinnvoll, wenn die Daten Strings sind.

Re: CSV auslesen

Verfasst: Dienstag 31. Januar 2023, 10:51
von Feedback1000
So, konnte das ganze mit euren Hinweisen jetzt zumindest mal zusammenschustern:

Code: Alles auswählen

import csv
from collections import defaultdict
from pathlib import Path
from pprint import pprint
import time

CLASSIFICATION_IDENTIFIER = (
    'PT',  # Punkte
    'SY',  # Symbole und gerichtete Punkte
    'PL',  # Linienzüge
    'SG',  # Gruppierte Linien
    'TX',  # Texte
    'FL',  # Flächen
)

ATTRIBUTE_IDENTIFIER = 'AT'  # Attribute zu einem Objekt
DELIMITER_CSV = ';'

CLASSIFICATION_OBJECT_KEYS = (
    'Objektart', 'Messcode', 'Bemerkung', 'Objekttyp', 'Beschreibung', 'Blockname', 'Layer', 'Kurzcode', 'Gruppe')
CLASSIFICATION_ATTRIBUTE_KEYS = (
    'Wert-ID', 'Wert-Spalte', 'Wert-Pos', 'Wert-Necessary', 'Wert-UebTab', 'Wert-Faktor', 'AT-Name', 'AT-Default',
    'Ausrichtung', 'SY-Art', 'SY-InsertMode', 'XSize', 'YSize', 'XSizeMin', 'XSizeMax', 'YSizeMin', 'YSizeMax',
    'XSize-ID', 'XSize-Pos', 'YSize-ID', 'YSize-Pos', 'SY-ZusObj', 'SY-EinsetzPkt', 'SY-RiCode', 'PosRechts', 'PosHoch',
    'Massband-Pos')

DATA_DIRECTORY = Path(
    r'C:/ProgramData/rmDATA/Shared/CodeGrafik')


def load_classification(filepath):
    classifications = defaultdict(list)
    with open(filepath) as csvdatei:
        reader = csv.DictReader(csvdatei, delimiter=DELIMITER_CSV)
        for line in reader:
            if line['Objektart'] in CLASSIFICATION_IDENTIFIER:
                current_classifications = {}
                for key, value in line.items():
                    if key in CLASSIFICATION_OBJECT_KEYS:
                        current_classifications[key] = value
                current_classifications['Attribute'] = []
                classifications[line['Objektart']].append(current_classifications)
            elif line['Objektart'] == ATTRIBUTE_IDENTIFIER and current_classifications:
                current_attributes = {}
                for key, value in line.items():
                    if key in CLASSIFICATION_ATTRIBUTE_KEYS:
                        current_attributes[key] = value
                current_classifications['Attribute'].append(current_attributes)
            else:
                current_classifications = None
    return classifications


def main():
    start = time.time()
    classifications = load_classification(
        DATA_DIRECTORY / 'VDLF.csv')
    # print(f'Anzahl Objekte: {len(classifications)}')
    # print(classifications.keys())
    pprint(classifications)
    for o in classifications:
        print(f'{o}: {len(classifications[o])}')
    ende = time.time()
    print('{:5.3f}s'.format(ende - start))

if __name__ == '__main__':
    main()
Aber zufrieden bin ich noch nicht...Seht ihr noch Verbesserungs-Potential? Wie ich euch kennen, ja. Würdet ihr dieses auch mit mit teilen?

Re: CSV auslesen

Verfasst: Dienstag 31. Januar 2023, 22:55
von sparrow
classifications heißt so, weil das die Mehrzahl von classification ist. Es ist eine Datenstruktur, die mehrere Elemente enthäkt.
current_classifications deutet im Namen ebenfalls darauf hin, dass es sich um etwas in der Mehrzahl handelt. Es ist aber nur eine classification, weshalb ich sie current_classification nennen würde.

Wenn man Textdateien öffnet, wie hier die CSV-Datei, sollte man nach Möglichkeit das Encoding entsprechend der Erwartung angeben. Sonst wird der Systemstandard verwendet, der von dem tatsächlichen Encoding abweichen kann.

Wenn den dem ganzen noch das i-Tüpfelchen aufsetzen möchtest: es gibt dict comprehensions, die sich an dieser Stelle anbieten würden.
Aus

Code: Alles auswählen

                current_classifications = {}
                for key, value in line.items():
                    if key in CLASSIFICATION_OBJECT_KEYS:
                        current_classifications[key] = value
                current_classifications['Attribute'] = []
                classifications[line['Objektart']].append(current_classifications)
würde dann

Code: Alles auswählen

                current_classification = {
                    k:v for k, v in line.items() if k in CLASSIFICATION_OBJECT_KEYS
                }
                current_classification['Attribute'] = []
                classifications[line['Objektart']].append(current_classification)
Und aus

Code: Alles auswählen

                current_attributes = {}
                for key, value in line.items():
                    if key in CLASSIFICATION_ATTRIBUTE_KEYS:
                        current_attributes[key] = value
                current_classifications['Attribute'].append(current_attributes)
würde

Code: Alles auswählen

                current_classification['Attribute'].append(
                    {k:v for k,v in line.items() if k in CLASSIFICATION_ATTRIBUTE_KEYS}
                )
(current_classification habe ich hier schon auf die Einzahl umbenannt)

Es ist aber ungetestet und es ist spät.
Ob man dict comprehensions nutzt ist ein bisschen eigene Geschmackssache. Zumindest in meinen Augen.

Ansonsten: Glückwunsch zum erarbeiteten Script.

Re: CSV auslesen

Verfasst: Samstag 4. Februar 2023, 11:43
von Feedback1000
@sparrow: Deine letzten Anmerkungen konnte ich einarbeiten.
@ALL: Vielen Dank eure Hilfe.