Datensatz eines Sensors plotten

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.
Wunderkind89
User
Beiträge: 66
Registriert: Sonntag 15. November 2020, 01:28

Hallo zusammen,
ich mache gerade mein Pflichtpraktikum seitens Studium. In diesem Praktikum geht es um 4 Sensoren, die Menschen in einer Sportanlage beim rein und rausgehen zählen (4 Gates).
Diese Sensoren liefern manchmal eine falsche Zählung und meine Aufgabe im Pflichtpraktikum lautet: Analyse von Sensordaten, insbesondere Zeitreihenverläufe.

Dazu hab ich einen Datensatz eines Sensors bekommen, der folgenden Form:

"";"zeit";"gate.1.in";"gate.1.out";"gate.2.in";"gate.2.out";"gate.3.in";"gate.3.out";"gate.4.in";"gate.4.out";"Total.Count"
"1";2020-10-31 09:57:35;0;0;0;0;0;0;0;0;0
"2";2020-10-31 09:57:36;0;0;0;0;0;0;0;0;0

Dieser Datensatz hat 235 Zeilen, von denen ich hier nur zwei zur Veranschaulichung gepostet habe.
Wie könnte ich jetzt diesen Datensatz mit matplotlib und python am Besten plotten?
Diese ganzen Simikolons und Gänsefüßchen stören doch, oder etwa nicht?
Ich arbeite mit pycharm und würde gern in meiner Konsole aus einer Datei lesen und das Ganze plotten (4 Grafiken, wo auf der x Achse die Uhrzeit und auf der y Achse die Häufigkeit der gezählten Menschen steht).

Geht das überhaupt oder wäre es umständlich und nicht ratsam?
Es ist meine dritte Woche (von insgesamt 12 Wochen) meines Praktikums und ich bin echt überfordert und komme kein Stück weiter.
Ich hab noch nie mit Python programmiert. Bis jetzt hab ich eine Häufigkeitsanalyse der Buchstaben an einem Text durchgeführt, was ich auch geschafft habe aber jetzt stehe ich vor einem neuen Problem, wo ich überhaupt nicht weiter weiß.
Wie könnte ich Zeilen für Zeilen von der Datei ablesen und diese plotten? Was würdet ihr mir raten?

Ich bin über jede Hilfe dankbar, da ich ein kompletter Neuling in Python bin

Liebe Grüße und bleibt alle gesund!
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

Solche Daten verarbeitet man am besten mit Pandas. Am besten erst einmal das Tutorial durcharbeiten: https://pandas.pydata.org/docs/getting_ ... ng-started

Code: Alles auswählen

import pandas as pd
daten = pd.read_csv("filename.csv", delimiter=";")
Wunderkind89
User
Beiträge: 66
Registriert: Sonntag 15. November 2020, 01:28

Muss ich dafür extra Jupyter installieren? Weil ich arbeite mit pycharm und da kann unter settings die panda "Bibliothek" installieren.

Den Beispielcode von You Tube habe ich in pycharm eingetippt:

import pandas as pd
import numpy as np

size = 100
index = pd.Series(range(0,size))
df = pd.DataFrame(np.random.randint(low =0, high =10, size=[size,4]), index = index, columns = ['A','B', 'C','D'])
df.head()

doch es passiert nichts, während der Typ im You Tube eine Ausgabe hatte.
Quelle: https://www.youtube.com/watch?v=iaziBEhdyRk&t=48s

pycharm müsste doch gehen, weil was macht es für einen Sinn dann, das ich dort die Panda "Bibliothek" einbinden kann. Ich wollte eigentlich bei pycharm bleiben.
Benutzeravatar
__blackjack__
User
Beiträge: 14053
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Wunderkind89: Die `head()`-Methode hat einen Rückgabewert mit dem Du nichts machst. Also ausgeben beispielsweise.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Wunderkind89
User
Beiträge: 66
Registriert: Sonntag 15. November 2020, 01:28

also kann ich einfach mit pycharm wie gewohnt weiter arbeiten?
Benutzeravatar
__blackjack__
User
Beiträge: 14053
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Wunderkind89: Ja.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Wunderkind89
User
Beiträge: 66
Registriert: Sonntag 15. November 2020, 01:28

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

DATA_FILE = "SmartCountr.csv"

df = pd.read_excel(DATA_FILE)

print(df.dataframe[3:6])

plt.show()

Error:
raise XLRDError('Unsupported format, or corrupt file: ' + msg)
xlrd.biffh.XLRDError: Unsupported format, or corrupt file: Expected BOF record; found b'"";"zeit'


Was mache ich hier falsch?

Die Anforderungen sollten sein:

1) lies die erste spalte der Excel Tabelle nicht, weil sie Nummerierung enthält
2) Trage die zweite Spalte aus der Excel Tabelle auf die x Achse, welche die laufende Zeit der Form 09:45 enthält
3) Trage die Häufigkeiten der darauffolgenden Spalten der Excel Tabelle als Werte zu dem jeweiligen Zeitpunkt
4) Skalliere die große Tabelle so, dass man die Daten gut sieht und die x,y Achse gut lesbar ist
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

Du hast keine XLS-Datei sondern eine CSV-Datei. Die liest man mit read_csv, dabei den richtigen delimiter angeben. Und laut 1. brauchst du noch ein Argument.
Wunderkind89
User
Beiträge: 66
Registriert: Sonntag 15. November 2020, 01:28

ich hab jetzt eine Ausgabe
Zuletzt geändert von Wunderkind89 am Dienstag 17. November 2020, 09:22, insgesamt 1-mal geändert.
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

Du gibst ja auch nicht an, was Du ausgeben möchtest.
Wunderkind89
User
Beiträge: 66
Registriert: Sonntag 15. November 2020, 01:28

import pandas as pd
import matplotlib.pyplot as plt

DATA_FILE = "SmartCountr.csv"

df = pd.read_csv(DATA_FILE, sep= ";", decimal=",", header=0, names=
["Number", "Time", "Gate 1 in", "Gate 1 out", "Gate 2 in", "Gate 2 out","Gate 3 in", "Gate 3 out",
"Gate 4 in", "Gate 4 out", "Total Count"],
usecols= ["Gate 1 in", "Gate 1 out", "Gate 2 in", "Gate 2 out","Gate 3 in", "Gate 3 out","Gate 4 in", "Gate 4 out"])

plt.plot(df)
plt.show()

Ich hab 15137 Zeilen insgesamt. Wie soll ich auf die x Achse die Zeit plotten?
Außerdem kriege ich 8 Graphen, von denen ich nicht weiß welcher Graph jetzt zu welchem Gate gehört.
Wunderkind89
User
Beiträge: 66
Registriert: Sonntag 15. November 2020, 01:28

Update:
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime

DATA_FILE = "SmartCountr.csv"

headers = ["Date", "Gate 1 in", "Gate 1 out", "Gate 2 in", "Gate 2 out", "Gate 3 in", "Gate 3 out", "Gate 4 in",
"Gate 4 out"]

use = ["Date", "Gate 1 in", "Gate 1 out", "Gate 2 in", "Gate 2 out","Gate 3 in", "Gate 3 out","Gate 4 in", "Gate 4 out"]
df = pd.read_csv(DATA_FILE, sep=";", decimal=",", header=0, names= headers, usecols=use)


df['Date'] = df['Date'].map(lambda x: datetime.strptime(str(x), '%Y/%m/%d %H:%M:%S.%f'))

x = df['Date']
y = df['Sensor Value']

plt.plot(x, y)
plt.gcf().autofmt_xdate()

FEHLER: ValueError: time data '1' does not match format '%Y/%m/%d %H:%M:%S.%f'
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

Nicht dass read_csv die Datumsspalte schon automatisch umwandelt und dass das Format nicht dem entspricht, das Du erwartest, aber da scheint wohl auch irgendwo ein nicht-Datumswert zu stehen.

Wenn Du eine Legende willst, mußt Du eine Legende plotten.
Wunderkind89
User
Beiträge: 66
Registriert: Sonntag 15. November 2020, 01:28

Sirius3 hat geschrieben: Dienstag 17. November 2020, 11:26 Nicht dass read_csv die Datumsspalte schon automatisch umwandelt und dass das Format nicht dem entspricht, das Du erwartest, aber da scheint wohl auch irgendwo ein nicht-Datumswert zu stehen.

Wenn Du eine Legende willst, mußt Du eine Legende plotten.
Verstehe ich es richtig? read_csv wandelt die Datumsspalte automatisch, also ist diese Zeile überflüssig:
df['Date'] = df['Date'].map(lambda x: datetime.strptime(str(x), '%Y/%m/%d %H:%M:%S.%f'))

Bei mir steht:
2020-10-31 09:57:35 (also erst Datum dann Zeit)

Meinst du mit "nicht Datumswert" die 1 vor dem Datum?

"1";2020-10-31 09:57:00

Was genau meinst du mit: das Format nicht dem entspricht, was ich erwarte?

Mein Datum hat doch die folgende Form: Jahr, Monat, Tag Stunde, Minute, Sekunde und das wäre korrekterweise: Y/%m/%d %H:%M:%S.

Liebe Grüße und danke euch an dieser Stelle, dass ihr mir hilft
Wunderkind89
User
Beiträge: 66
Registriert: Sonntag 15. November 2020, 01:28

An der Stelle y = df['Sensor Value']
müssten da wo "Sensor Value" steht, meine 4 Sensoren stehen
Wunderkind89
User
Beiträge: 66
Registriert: Sonntag 15. November 2020, 01:28

Update:

Ich hab jetzt folgendes gemacht: ich hab von meiner csv Datei die erste Spalte gelöscht und das ganze nach links verschoben. Die erste Spalte war eh eine Nummerierung. Beim abspeichern hatte ich jedoch einen Datenverlust, so dass alle meine Sekunden auf 00 gesetzt wurden, also habe ich das Ganze in xlsx abgespeichert und mein Programm entsprchend angepasst. Jetzt kommt neue Fehlermeldung, mit der ich überhaupt nichts anfangen kann:

import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime

DATA_FILE = "SmartCountr.xlsx"


df = pd.read_excel(DATA_FILE, header=0, names= ["Date", "Gate 1 in", "Gate 1 out", "Gate 2 in", "Gate 2 out","Gate 3 in", "Gate 3 out",
"Gate 4 in", "Gate 4 out", "Total Count"],
usecols= ["Date", "Gate 1 in", "Gate 1 out", "Gate 2 in", "Gate 2 out","Gate 3 in", "Gate 3 out","Gate 4 in", "Gate 4 out"])

df['Date'] = df['Date'].map(lambda x: datetime.strptime(str(x), '%d/%m/%Y %H:%M:%S.%f'))

x = df["Date"]
y = df["Gate 1 in"]

plt.plot(x, y)
plt.gcf().autofmt_xdate()

AttributeError: 'ElementTree' object has no attribute 'getiterator'
Wunderkind89
User
Beiträge: 66
Registriert: Sonntag 15. November 2020, 01:28

Update:

Ich hab das Programm fast fertig, auch wenn es nicht ganz so schön programmiert wurde (siehe die vielen plots): Das Programm Zeigt mir alles, was ich brauche, bis auf die Zeit. Ich will die Zeit auf meiner x-Achse darstellen, jedoch klappt es irgendwie immer noch nicht und es kommt eine Fehlermeldung:

import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime

DATA_FILE = "SmartCountr.xls"

df = pd.read_excel(DATA_FILE)

df['Date'] = df['Date'].map(lambda x: datetime.strptime(str(x), '%Y-%m-%d %H:%M:%S.%f'))

Date = df["Date"]

Gate_1_i = df["Gate 1 in"]
Gate_1_o = df["Gate 1 out"]

Gate_2_i = df["Gate 2 in"]
Gate_2_o = df["Gate 2 out"]

Gate_3_i = df["Gate 3 in"]
Gate_3_o = df["Gate 3 out"]

Gate_4_i = df["Gate 4 in"]
Gate_4_o = df["Gate 4 out "]

plt.xlabel("Time", family='serif', color='r', weight='normal', size = 16, labelpad = 6)
plt.ylabel("Frequency", family='serif', color='b', weight='normal', size = 16, labelpad = 6)
plt.suptitle('Sensor measurement errors', fontsize=16)


plt.plot(Date, Gate_1_i, label = "Gate 1 in")
plt.plot(Date, Gate_1_o, label = "Gate 1 out")
plt.plot(Date, Gate_2_i, label = "Gate 2 in")
plt.plot(Date, Gate_2_o, label = "Gate 2 out")
plt.plot(Date, Gate_3_i, label = "Gate 3 in")
plt.plot(Date, Gate_3_o, label = "Gate 3 out")
plt.plot(Date, Gate_4_i, label = "Gate 4 in")
plt.plot(Date, Gate_4_o, label = "Gate 4 out")

leg = plt.legend()
plt.show()


Fehler: ValueError: time data '2020-10-31 09:57:35' does not match format '%Y-%m-%d %H:%M:%S.%f'

Ich hab schon vieles Probiert, aber irgendwie schaffe ich es nicht, die Zeit auf die x-Achse zu plotten.

Kann mir jemand weiter helfen?

Grüße
Benutzeravatar
__blackjack__
User
Beiträge: 14053
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Wunderkind89: Was hat denn die "Date"-Spalte in dem Dataframe für einen Datentyp das Du denkst da `str()` auf den Werten aufrufen zu müssen? Nicht das Du da einen Zeitstempel-Datentyp erst mit `str()` in eine Zeichenkette wandelst nur um die dann mit `datetime.strptime()` wieder in einen Zeitstempel-Datentyp umzuwandeln‽ Denn falls da schon Zeitstempel in der Exceltabelle stehen, dann werden die ja nicht als Zeichenketten eingelesen sondern schon in einem entsprechend passenden Datentyp.

Was da beim Muster nicht stimmt ist doch eigentlich recht offensichtlich. Geh doch einfach mal manuell das Muster durch und sag mal welcher Teil des Musters auf welchen Teil von der Zeichenkette passt die da in der Fehlermeldung angegeben ist. Da sollte dann etwas auffallen.

Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase).

Namen sollten weder nummeriert werden noch kryptische Abkürzungen enthalen oder gar nur daraus bestehen. `leg` heisst auf Deutsch „Bein“ und ist eher verwirrend wenn damit eine „Legende“ gemeint ist. Wobei dieser Name dann gar nicht verwendet wird.

Da ist viel Code der gleichförmig ist und nach kopieren und leicht anpassen aussieht. Programmierer sind aber faul. Die gute Art von faul und vermeiden Redundanz in Code und Daten. So etwas macht man mit einer Schleife statt den nahezu gleichen Code zu wiederholen.

Zwischenstand (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python3
from datetime import datetime

import matplotlib.pyplot as plt
import pandas as pd

DATA_FILENAME = "SmartCountr.xls"


def main():
    data = pd.read_excel(DATA_FILENAME)
    data["Date"] = data["Date"].map(
        lambda x: datetime.strptime(x, "%Y-%m-%d %H:%M:%S.%f")
    )

    for label in (
        f"Gate {number} {direction}"
        for number in range(1, 5)
        for direction in ["in", "out"]
    ):
        plt.plot(data["Date"], data[label], label=label)

    axis_label_arguments = {
        "family": "serif",
        "weight": "normal",
        "size": 16,
        "labelpad": 6,
    }
    plt.xlabel("Time", color="r", **axis_label_arguments)
    plt.ylabel("Frequency", color="b", **axis_label_arguments)
    plt.suptitle("Sensor measurement errors", fontsize=16)
    plt.legend()
    plt.show()


if __name__ == "__main__":
    main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

Wunderkind89 hat geschrieben: Dienstag 17. November 2020, 18:55 Ich hab jetzt folgendes gemacht: ich hab von meiner csv Datei die erste Spalte gelöscht und das ganze nach links verschoben.
WARUM??? Du hast eine Programmiersprache vor Dir, Du hast außerdem pandas, das alle Funktionalität dafür schon mitbringt. Warum löscht Du dann händisch eine Spalte, inklusive den ganzen Problemen, die Du damit beschreibst????

Hier Dein Code von früher, wo einfach nur die Nummer fehlte:

Code: Alles auswählen

headers = ["Nummer", "Date", "Gate 1 in", "Gate 1 out", "Gate 2 in", "Gate 2 out", "Gate 3 in", "Gate 3 out", "Gate 4 in", "Gate 4 out"]
df = pd.read_csv(DATA_FILE, sep=";", decimal=",", header=0, names= headers, usecols=headers[1:])
Wunderkind89
User
Beiträge: 66
Registriert: Sonntag 15. November 2020, 01:28

@Sirius

Ich hab die erste Spalte gelöscht, weil da zum einen dort "nur" eine Nummerierung stand, die für eine graphische Darstellung nicht wichtig war (so denke ich zumindest) und zum anderen, weil ich (noch) nicht weiß, wie ich auf die nächste Spalte zugreifen kann. Bei mir wurde das Datum in der falschen Spalte abgelesen: FEHLER: ValueError: time data '1' does not match format '%Y/%m/%d %H:%M:%S.%f'

Aber ich kann dein Argument sehr gut nachvollziehen, dass ich mir dadurch unnötig viel Arbeit gemacht habe und zum anderen, dass man dadurch wichtige Informationen verlieren kann, wenn man nicht aufpasst, besonders beim abspeichern der Excel Tabelle.
Antworten