Aus einer Excel-Datei mit Python bestimmte Zeile ausgeben lassen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
python_beginner.98
User
Beiträge: 22
Registriert: Dienstag 20. September 2022, 12:19

Der Code ist in Teilen nun wie folgt:

Code: Alles auswählen

import sys
!{sys.executable} -m pip install prettyprinter

from collections import namedtuple
from contextlib import closing

import openpyxl
from more_itertools import first_true, grouper
from prettyprinter import cpprint


Item = namedtuple("Parameter", "x y v atan alat timestamp")
Project = namedtuple("Trajektorie", "ID items")


def create_from_column(column_values):
    column_values = iter(column_values)
    return Project(
        next(column_values),
        [Item(*group) for group in grouper(column_values, 6, "strict")],
    )


def load_excel(file_path):
    with closing(openpyxl.open(file_path)) as workbook:
        return list(
            map(
                create_from_column,
                workbook.worksheets[0].iter_cols(min_col=2, values_only=True),
            )
        )


def search_item(project, min_timestamp):
    return first_true(
        project.items, None, lambda project: project.timestamp > min_timestamp
    )


def main():
    projects = load_excel("Test.xlsx")
    cpprint(projects)
    print("-" * 70)
    for project in projects:
        print(project.ID, ":", search_item(project, 2))


if __name__ == "__main__":
    main()
Darin kann ich unten mit dem kleinen Teil

Code: Alles auswählen

search_item(project, 2))
mit der Zahl (in diesem Fall 2) den gewollten Zeitstempel wählen.
Als Ausgabe bekomme ich dann die zugehörigen Daten, wenn der Timestamp zum ersten mal erreicht ist:

Code: Alles auswählen

1 : Parameter(x=410574.85, y=5653917.24, v=0.0083, atan=0.0111, alat=-0.0492, timestamp=2.002)
2 : Parameter(x=410576.27, y=5653912.7, v=14.059, atan=-1.0263, alat=1.3111, timestamp=2.002)
3 : Parameter(x=410570.81, y=5653915.15, v=1.5975, atan=-0.6558, alat=-0.0103, timestamp=2.002)
4 : Parameter(x=410568.75, y=5653895.86, v=15.2532, atan=-0.3959, alat=0.024, timestamp=2.002)
5 : Parameter(x=410584.78, y=5653915.04, v=26.8599, atan=0.7595, alat=0.0988, timestamp=11.244567)
6 : Parameter(x=410527.93, y=5653907.68, v=29.8087, atan=-0.5317, alat=0.0409, timestamp=16.4164)
7 : Parameter(x=410568, y=5653884.21, v=21.9894, atan=-0.5353, alat=-0.6291, timestamp=18.852167)
8 : Parameter(x=410568.28, y=5653884.21, v=33.1464, atan=-0.584, alat=-0.4838, timestamp=27.6276)
9 : Parameter(x=410568.38, y=5653884.26, v=25.5369, atan=-0.5661, alat=-0.5998, timestamp=29.763067)
10 : Parameter(x=410568.13, y=5653922.85, v=5.298, atan=0.0337, alat=-0.0164, timestamp=37.9379)
Darin sind also alle Werte aus dem Tuple, wenn der Wert 2 zum ersten mal überschritten wird.
Problem ist nur wie gesagt, dass sozusagen jede Datenserie nicht gleichzeitig bei 0s beginnt, sondern fortlaufend später. Bei 5: Parameter ist der timestamp zB 11.244567. Dies ist allerdings der Startwert, da die Daten in dieser Spalte erst zu dieser zeit beginnen.

Der Grenzwert des timestamp soll demzufolge nicht immer genau bei 2s liegen, sondern ab Beginn des ersten Wertes 2s betragen. Demzufolge Startwert+2s und dann die entsprechenden zugehörigen Parameter des Tuple anzeigen.
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das sollte dann einfach

Code: Alles auswählen

search_item(project, project.items[0].timestamp + 2)
sein - oder sowas in der Art.
python_beginner.98
User
Beiträge: 22
Registriert: Dienstag 20. September 2022, 12:19

Vielen Dank für die schnelle Antwort. Ich glaube damit sollte es möglich sein das einzubauen. Vielen Dank.

Wie lautet der Befehl, dass ich mir den letzten Teil der Ausgabe als eine neue Excel-Datei automatisch speichere?
Also ich meine nur den folgenden Teil:

Code: Alles auswählen

1 : Parameter(x=410574.85, y=5653917.24, v=0.0083, atan=0.0111, alat=-0.0492, timestamp=2.002)
2 : Parameter(x=410576.27, y=5653912.7, v=14.059, atan=-1.0263, alat=1.3111, timestamp=2.002)
3 : Parameter(x=410570.81, y=5653915.15, v=1.5975, atan=-0.6558, alat=-0.0103, timestamp=2.002)
4 : Parameter(x=410568.23, y=5653901.73, v=9.5266, atan=-0.0238, alat=0.3988, timestamp=3.770433)
5 : Parameter(x=410571.85, y=5653914.41, v=17.8563, atan=-1.0628, alat=2.2781, timestamp=13.246567)
6 : Parameter(x=410543.76, y=5653909.55, v=24.1771, atan=-2.2711, alat=-0.246, timestamp=18.4184)
7 : Parameter(x=410567.66, y=5653897.41, v=22.854, atan=-1.5908, alat=0.1954, timestamp=20.854167)
8 : Parameter(x=410567.12, y=5653901.11, v=25.6882, atan=-1.4067, alat=0.1826, timestamp=29.6296)
9 : Parameter(x=410567.43, y=5653898.75, v=23.7963, atan=-1.7227, alat=0.1973, timestamp=31.765067)
10 : Parameter(x=410568.56, y=5653920.1, v=4.9948, atan=0.146, alat=-0.05, timestamp=39.9399)
Vorher werden ja über viele 1000 Zeilen die einzelnen Tupel dargestellt. Diese benötige ich nicht, lediglich die Ausgabe ganz am Ende.
Mit welchem Code-Befehl kann ich diesen Teil in einer Excel speichern?
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wir waren doch schon dabei, dass einfach Code abzuliefern hier eher nicht so unser Ding ist. Du benutzt doch schon openpyxl, hast du dich damit auseinandergesetzt, wie das Excel Datein schreibt? Mal eine schreiben lassen, erstmal mit fixem Inhalt? Dann versuchen, die daten, die du da hast, einzupflegen?
python_beginner.98
User
Beiträge: 22
Registriert: Dienstag 20. September 2022, 12:19

Ja damit habe ich mich auseinandergesetzt. Allerdings finde ich keinen Ansatz, die ersten 1000+ Zeilen nicht zu speichern sondern nur die letzten 10 interessanten Zeilen in eine excel einzupflegen.
Ich fordere ja keinen vollständigen Code..ich benötige nur etwas Hilfe in den Ansätzen etc..
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Und wo findet sich dieses Auseinandersetzung? Ich sehe keinen Code, der 1000+ Zeilen schreibt.
python_beginner.98
User
Beiträge: 22
Registriert: Dienstag 20. September 2022, 12:19

Der oben von mir geschickte Code liefert 1000+ Zeilen als Ergebnisse. Die 10 Parameter welche ich oben als Ergebnis angegeben habe sind davon genau diese letzten Zeilen, die ich ausschließlich speichern möchte. Darüber bringt der Code noch sehr viele "Zwischenergebnisse".
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das war nicht die Frage. Du wolltest wissen, wie man die gefilterten Datei schreibt. Wie man beispielhaft Daten schreibt steht in der Dokumentation. Das kann man also ausprobieren. Und dann mit den gefilterten Daten bestücken, statt Beispieldaten. Ich sehe aber nichts, was da als auch nur als Ansatz eines Ansatzes gelten kann. Somit sieht’s halt aus wie das übliche um fertige Lösung bitten aus. Oder woran meinst du macht sich da ein Unterschied fest? Weil du sagst, es ist nicht so?
python_beginner.98
User
Beiträge: 22
Registriert: Dienstag 20. September 2022, 12:19

Ich suche ja auch lediglich nach einem Befehl, um die Ergebnisse dieser "main()"-Funktion als eine Excel abzuspeichern und davon nicht alle Ergebnisse sondern die letzten für mich interessanten (letzten 10).
Ich habe dies mit dem einfachen .save Befehl versucht. Dies klappt aber nicht. Der .to_excel Befehl funktioniert ja nicht weil es sich dabei um Pandas handelt und nicht openpyxl..
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Sprichwoertlich der erste Block Code in der Dokumentation von openpyxl ist ein Beispiel, wie man ein Workbook neu erzeugt, Daten einfuegt, und das speichert. https://openpyxl.readthedocs.io/en/stable/

Und das musst du nehmen, und statt der Beispieldaten deine Daten benutzen. Und achtung: einfach nur ein simples append mit deinen Daten reicht *nicht*, denn die sind repraesnetiert in einer openpyxl unbekannten Objekt-Struktur. Die musst du da schon mit den absoluten Grundlagen aus Schleifen, und Listen, rauspulen. Das ist programmieren. Nicht "den einen Befehl" suchen. Den gibt's naemlich nicht.
python_beginner.98
User
Beiträge: 22
Registriert: Dienstag 20. September 2022, 12:19

Diese einfachen Dinge wie man eine excel aufbaut etc. habe ich bereits einige Male genutzt und so einfache Matrizen generiert.
Das Problem liegt bei mir darin, wie ich meine Daten einbaue.
Wie folgt funktioniert es nicht:

Code: Alles auswählen

book = Workbook()
sheet= book.active

rows = (main())

for row in rows:
    sheet.append(row)
book.save('werte.xlsx')
Dabei tritt der Fehler : "TypeError: 'NoneType' object is not iterable" auf.
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Und was gibst du so zurueck, mit return, aus deiner main?

Was du so alles weisst, und probiert hast, kann ich uebrigens nicht wissen. Vages Gerede von "also ich habe da diesen save-Befehl probiert" hilft halt nicht. Code hilft. Immer. Und auch eher aller. Nicht nur kuratierte Ausschnitte, von denen du gar nicht weisst, ob die ausreichend sind, oder nicht. So wie hier.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Du brauchst halt eine Funktion, die auch wirklich `rows` zurückliefert und nicht per `print` ausgibt.
python_beginner.98
User
Beiträge: 22
Registriert: Dienstag 20. September 2022, 12:19

Mein Code am Ende der Ausgabe sieht jetzt so aus:

Code: Alles auswählen

def main():
    projects = load_excel("Test.xlsx")
    #cpprint(projects) #zeigt alle Tupel aller Zeitpunkte mit den 6 Parametern
    print("-" * 70)
    for project in projects:
        print(project.ID, ":", search_item(project,project.items[0].timestamp + 1.5) ) #nutzt gewählte min.-Zeit ab erster aufgenommener Zeit (ab wann im Ausschnitt)


if __name__ == "__main__":
    main()
Dieser liefert mir jetzt ausschließlich die für mich interessanten Werte wie folgt:

1 : Parameter(x=410574.85, y=5653917.24, v=0.0086, atan=0.0079, alat=-0.0782, timestamp=1.8018)
2 : Parameter(x=410575.49, y=5653912.62, v=14.5366, atan=-0.9815, alat=1.5417, timestamp=1.8018)
3 : Parameter(x=410570.91, y=5653915.15, v=2.1496, atan=-0.8441, alat=-0.0195, timestamp=1.8018)
4 : Parameter(x=410568.24, y=5653901.19, v=9.6236, atan=-0.2598, alat=0.3591, timestamp=3.570233)
5 : Parameter(x=410572.88, y=5653914.27, v=18.7566, atan=-1.4057, alat=1.9382, timestamp=13.046367)
6 : Parameter(x=410542.4, y=5653909.38, v=25.7907, atan=-2.1727, alat=-0.2372, timestamp=18.2182)
7 : Parameter(x=410567.79, y=5653896.14, v=23.992, atan=-1.5106, alat=0.0935, timestamp=20.653967)
8 : Parameter(x=410567.33, y=5653899.66, v=26.8394, atan=-1.7265, alat=0.0376, timestamp=29.4294)
9 : Parameter(x=410567.62, y=5653897.42, v=25.0916, atan=-1.7904, alat=0.0665, timestamp=31.564867)
10 : Parameter(x=410568.5, y=5653920.37, v=4.8911, atan=0.136, alat=-0.1122, timestamp=39.7397)

Anschließend habe ich versucht, diese mit openpyxl durch das Workbook in eine neu entstandene Excel zu speichern wie folgt:

Code: Alles auswählen

book = Workbook()
sheet = book.active

rows = (main())

for row in rows:
    sheet.append(row)

book.save('Ergebnisse.xlsx')
Daraus resultiert eben dieser Fehler wie oben genannt. Laut einigen Foren etc. kann ich durch das Einsetzen von return dem entgegenwirken. Nur leider finde ich keine Hinweise wo genau dies an der Stelle eingebracht werden muss.
Oder kann man auch direkt bei der Zeile "print(project.ID, ":", search_item(project,project.items[0].timestamp + 2)“ nicht das print nutzen sondern direkt abspeichern in einer Tabellenform?
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Du verwendest for-Schleifen, Du verwendest Listen, Du hast also schon alle Werkzeuge, um Dein Problem zu lösen.
Wie schon geschrieben, mußt Du eine Funktion schreiben, die statt wie in `main` die Werte per print auszugeben, diese Werte in einer Liste speichert, damit Du sie dann in Deinem neuen "main" das Ergebnis in eine Exceltabelle schreiben kannst.
python_beginner.98
User
Beiträge: 22
Registriert: Dienstag 20. September 2022, 12:19

Das bedeutet den folgenden Teil benötige ich aber auch? :

Code: Alles auswählen

book = Workbook()
sheet = book.active

rows = (main())

for row in rows:
    sheet.append(row)

book.save('Ergebnisse.xlsx')
Ich habe versucht direkt bei der Main-Funktion das speichern einzubringen. Dabei bekomme ich den Fehler :"AttributeError: 'tuple' object has no attribute 'save'
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Und wieder postest Du die Fehlermeldung, ohne den dazugehörigen Code.
Programmieren besteht darin, ein großes Problem in so kleine Teile zu Teilen, dass sie einfach zu lösen sind. Dein Problem Daten aus Excel lesen, filtern und wieder nach Excel schreiben, besteht ja natürlicherweise aus drei Teilen, wobei das Programm das __blackjack__ für Dich geschrieben hat, das Problem Daten aus Excel lesen, filtern und per print ausgeben löst.
Deshalb ja der Hinweis, das print durch speichern in Excel zu ersetzen. Und braucht man dafür Code, der ein Workbook erzeugt, Daten in ein Sheet schreibt und das als xlsx-Datei speichert?
python_beginner.98
User
Beiträge: 22
Registriert: Dienstag 20. September 2022, 12:19

Sorry das ich keinen Code mit hatte. Ich habe es jetzt versucht so in die Struktur einzubringen:

Code: Alles auswählen

def main():
    projects = load_excel("Test.xlsx")
    #cpprint(projects) #zeigt alle Tupel aller Zeitpunkte mit den 6 Parametern
    print("-" * 70)
    for project in projects:
        workbook=Workbook()
        sheet=workbook.active
        data=[(project.ID, ":", search_item(project,project.items[0].timestamp + 1.8))] #nutzt gewählte min.-Zeit ab erster aufgenommener Zeit (ab wann im Ausschnitt)
    for row in data:
        sheet.append(row)
    workbook.save("Ergebnisse.xlsx")
        
if __name__ == "__main__":
    main()
Dabei tritt der Fehler auf: "ValueError: Cannot convert Parameter(x=410568.5, y=5653920.37, v=4.8911, atan=0.136, alat=-0.1122, timestamp=39.7397) to Excel"
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das habe ich ja schon erwaehnt, dass das nicht geht.
Und achtung: einfach nur ein simples append mit deinen Daten reicht *nicht*, denn die sind repraesnetiert in einer openpyxl unbekannten Objekt-Struktur. Die musst du da schon mit den absoluten Grundlagen aus Schleifen, und Listen, rauspulen.
python_beginner.98
User
Beiträge: 22
Registriert: Dienstag 20. September 2022, 12:19

Ok alles klar. Hätten sie Hinweise wie ich das Problem löse? Da ich mit dieser Erklärung leider keine Ahnung habe wonach ich suchen sollte um passende Ansätze für die Lösung dieses Problems zu finden. Es ist ja scheinbar soweit alles korrekt an dem Code und es handelt sich nun ausschließlich um das korrekte "einsortieren" in eine Excel.
Antworten