Seite 1 von 2

Datensatz eines Sensors plotten

Verfasst: Montag 16. November 2020, 17:21
von Wunderkind89
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!

Re: Datensatz eines Sensors plotten

Verfasst: Montag 16. November 2020, 17:30
von Sirius3
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=";")

Re: Datensatz eines Sensors plotten

Verfasst: Montag 16. November 2020, 18:41
von Wunderkind89
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.

Re: Datensatz eines Sensors plotten

Verfasst: Montag 16. November 2020, 19:09
von __blackjack__
@Wunderkind89: Die `head()`-Methode hat einen Rückgabewert mit dem Du nichts machst. Also ausgeben beispielsweise.

Re: Datensatz eines Sensors plotten

Verfasst: Montag 16. November 2020, 19:17
von Wunderkind89
also kann ich einfach mit pycharm wie gewohnt weiter arbeiten?

Re: Datensatz eines Sensors plotten

Verfasst: Montag 16. November 2020, 20:54
von __blackjack__
@Wunderkind89: Ja.

Re: Datensatz eines Sensors plotten

Verfasst: Dienstag 17. November 2020, 01:24
von Wunderkind89
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

Re: Datensatz eines Sensors plotten

Verfasst: Dienstag 17. November 2020, 07:10
von Sirius3
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.

Re: Datensatz eines Sensors plotten

Verfasst: Dienstag 17. November 2020, 08:58
von Wunderkind89
ich hab jetzt eine Ausgabe

Re: Datensatz eines Sensors plotten

Verfasst: Dienstag 17. November 2020, 09:13
von Sirius3
Du gibst ja auch nicht an, was Du ausgeben möchtest.

Re: Datensatz eines Sensors plotten

Verfasst: Dienstag 17. November 2020, 10:15
von Wunderkind89
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.

Re: Datensatz eines Sensors plotten

Verfasst: Dienstag 17. November 2020, 10:56
von Wunderkind89
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'

Re: Datensatz eines Sensors plotten

Verfasst: Dienstag 17. November 2020, 11:26
von Sirius3
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.

Re: Datensatz eines Sensors plotten

Verfasst: Dienstag 17. November 2020, 11:48
von Wunderkind89
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

Re: Datensatz eines Sensors plotten

Verfasst: Dienstag 17. November 2020, 11:55
von Wunderkind89
An der Stelle y = df['Sensor Value']
müssten da wo "Sensor Value" steht, meine 4 Sensoren stehen

Re: Datensatz eines Sensors plotten

Verfasst: Dienstag 17. November 2020, 18:55
von Wunderkind89
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'

Re: Datensatz eines Sensors plotten

Verfasst: Mittwoch 18. November 2020, 01:26
von Wunderkind89
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

Re: Datensatz eines Sensors plotten

Verfasst: Mittwoch 18. November 2020, 02:11
von __blackjack__
@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()

Re: Datensatz eines Sensors plotten

Verfasst: Mittwoch 18. November 2020, 08:39
von Sirius3
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:])

Re: Datensatz eines Sensors plotten

Verfasst: Mittwoch 18. November 2020, 10:05
von Wunderkind89
@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.