[PYTHON] Entwicklungsmemorandum ~ Pandas, Prognose, Datenstruktur ~

Überblick

Vor kurzem hatte ich die Möglichkeit, meine Arbeit zu automatisieren. Was den Inhalt betrifft,

Es war eine relativ einfache Sache. Der derzeitige Perfektionsgrad liegt bei ca. 80%. Es war schwieriger als ich erwartet hatte und ich habe viele Dinge, also schreibe ich diesen Artikel, damit ich ihn für die Zukunft zusammenfassen kann. Es mag ein wenig chaotisch sein, aber ich hoffe, Sie können es mit warmen Augen sehen.

Wissen

Das Folgende ist eine Zusammenfassung des Lernens über Wissen, hauptsächlich Bibliotheken und Programmspezifikationen.

1.) Zuweisung von pandas.DataFrame zeigt auf dasselbe Objekt

Ich denke, dies ist eine Selbstverständlichkeit für diejenigen, die mit Datenrahmen vertraut sind. Ich habe den gleichen Fehler beim Umgang mit Listen gemacht, aber ich habe nicht daran gedacht und es erneut gemacht.

Die Situation ist, dass Sie versuchen, ein Wörterbuch mit einem Datum / Uhrzeit-Typ als Schlüssel mit einem leeren Datenrahmen zu initialisieren, wie unten gezeigt. Ich habe es so gemacht: "Ich möchte Personen, die Abschnitte verwenden, nach Datum gruppieren, also vorerst einen leeren Datenrahmen registrieren!"

python


import pandas as pd
import datetime


empty_user = dict(Section1=['', '', ''], Section2=['', '', ''], Section3=['', '', ''])
hour = ['9:00', '10:00', '11:00']
df = pd.DataFrame(data=empty_user, index=hour)

five_days_list = [(datetime.datetime(2020, 9, 1) + datetime.timedelta(days=1) * i) for i in range(5)]
dict_of_dataframe = {date_key : df for date_key in five_days_list}

Das fertige Wörterbuch sieht so aus.

date_key : 2020-09-01 00:00:00
value :
      Section1 Section2 Section3
9:00                            
10:00                           
11:00                           
date_key : 2020-09-02 00:00:00
#Unten weggelassen

Vor ungefähr einer Woche hatte ich keine Zweifel und ging zur nächsten Aufgabe über. Wenn ich jedoch mit der Registrierung der aggregierten Daten beginne, funktioniert dies überhaupt nicht. Von dem Zeitplan für ungefähr einen Monat sind der dritte und die folgenden Tage durcheinander.

Der Grund ist einfach, wenn ich jetzt darüber nachdenke. Diese Erstellungsmethode verwendet einfach immer wieder denselben Datenrahmen. Es wird deutlicher, wenn Sie mit id () ausgeben.

python


for date_key, dataframe in dict_of_dataframe.items():
    print(f"date_key : {date_key}")
    print(f"dataframe_id : {id(dataframe)}")
date_key : 2020-09-01 00:00:00
dataframe_id : 2124838088520
date_key : 2020-09-02 00:00:00
dataframe_id : 2124838088520
date_key : 2020-09-03 00:00:00
#Unten weggelassen

Um richtig zu sein, musste ich copy () verwenden, eine Methode von pandas.DataFrame.

python


dict_of_dataframe = {date_key : df.copy() for date_key in five_days_list}
date_key : 2020-09-01 00:00:00
dataframe_id : 2124838588936
date_key : 2020-09-02 00:00:00
dataframe_id : 2124838590152
date_key : 2020-09-03 00:00:00

Offizielles Dokument von Pandas, aber es ist eine Kopie des Datenrahmens. Die () -Methode ist standardmäßig deep = True, eine tiefe Kopie. Wenn Sie es nur als Vorlage verwenden möchten, müssen Sie es als Objekt verwenden. Als ich es bemerkte, fühlte ich den Schock, getroffen zu werden.

Wie später beschrieben wird, wurde diese Arbeit von einer ziemlich tiefen Datenstruktur und der damit verbundenen Mehrfachschleifenstruktur begleitet. Anfangs war ich nur um diese Person besorgt, daher glaube ich, dass ich ungefähr zwei Tage lang unter dem Kampf um dieses und jenes gelitten habe, wie z. B. die Ausgabe des Fortschritts, das Lesen des Pandas-Dokuments, das Schreiben der Schleifenstruktur auf Papier usw. Ich werde.

2.) für: sonst: ist sehr praktisch

Ich dachte, ich wüsste etwas über die grundlegende Grammatik von Python, aber ich traf dieses Kind zum ersten Mal während der Entwicklung. Oder ich wusste es, vergaß es aber. Wenn Sie die else-Anweisung zusammen mit der for-Anweisung verwenden, wird die else-Anweisung nur dann ausgeführt **, wenn Sie die Schleife der for-Anweisung ** nicht unterbrechen können.

Ich denke, es gibt unzählige Verwendungszwecke, aber ich habe es verwendet, um eine Protokollbenachrichtigung zu erhalten, wenn es keinen freien Abschnitt gibt, wie unten gezeigt.

python


client_salesman_dict = {datetime.datetime(2020, 9, 1, 9, 0) :  [('Herr Yamada', 'Takahashi'), ('Herr Yoshizawa', 'Ito')],
                        datetime.datetime(2020, 9, 1, 10, 0) : [('Herr Sasaki', 'Momoyama')],
                        datetime.datetime(2020, 9, 1, 11, 0) : [('Herr Yokota', 'Takahashi'), ('Fukuchi', 'großer Baum'), ('Herr Nakayama', 'Ito'), ('Herr Gonda', 'Ozawa')],}

section_list = ['Section1', 'Section2', 'Section3',]

for date_dt, client_salesman_tuples in client_salesman_dict.items():
    date_str = f"{date_dt.hour}:{date_dt.minute:02}"
    
    for client_salesman_tuple in client_salesman_tuples:
        client = client_salesman_tuple[0]
        salesman = client_salesman_tuple[1]
        
        for section in section_list:
            section_status = df.loc[date_str, section]
            print(f"client : {client}, salesman : {salesman}")
            print(f"time is {date_str}")
            print(f"section is {section}")
            print(f"section_status is {section_status}")
            if section_status:
                print(f"bool of section_status is {bool(section_status)}.")
                print("I will skip writing phase.")
                continue
            print(f"I have applied {client},{salesman} to {section}")
            df.loc[date_str, section] = f"{client} {salesman}"
            break
            
        else:
            print(f"There is no empty section for{client}, {salesman}.Please recheck schedule.")
client :Herr Yamada, salesman :Takahashi
time is 9:00
section is Section1
section_status is 
Ich habe Herrn Yamada beantragt,Takahashi zu Abschnitt 1
client :Herr Yoshizawa, salesman :Ito
time is 9:00
section is Section1
section_Status ist Herr Yamada Takahashi
bool of section_status is True.
I will skip writing phase.
#Unterlassung
Es gibt keinen leeren Abschnitt für Gonda,Ozawa.Please recheck schedule.

Es war einmal, als ich eine ähnliche Verarbeitung in C-Sprache oder Java durchführte, ich glaube, ich habe mein Bestes mit einem darin gesetzten Flag gegeben, aber es scheint für Python unnötig. Es ist nüchtern, aber es gibt viele Möglichkeiten, den for-Satz selbst zu verwenden, daher möchte ich ihn weiterhin entsprechend verwenden.

3.) Eins _ vor dem Attribut ist eine übliche private Deklaration, zwei _ machen es auf die übliche Weise unzugänglich

Ich wusste, dass es schon lange existiert, aber ich habe nicht darauf geachtet und es selbst benutzt. Wenn Sie das Verhalten richtig testen, sehen Sie so etwas.

python


class TestClass:
    def __init__(self):
        self.hoge = 1
        self._fuga = 2
        self.__monge = 3
    
    def _foo1(self):
        print("_foo1 is called")
    
    def __foo2(self):
        print("__foo2 is called")

t = TestClass()

#Instanzvariable
print(t.hoge)
print(t._fuga)
# print(t.__monge)← Ich kann nicht anrufen
print(t._TestClass__monge)

#Klassenmethode
t._foo1()
# t.__foo2()← Ich kann nicht anrufen
t._TestClass__foo2()
1
2
3
_foo1 is called
__foo2 is called

Wenn Sie zu Beginn zwei Unterstriche hinzufügen, können Sie Instanzvariablen oder Klassenmethoden nicht wie gewohnt aufrufen. Es ist jedoch kein robustes privates Attribut wie in Java.

python


instance.__ClassName_AttributeName

Es ist möglich, es mit zu nennen.

Auch wenn Sie am Anfang einen Unterstrich setzen ... können Sie dies auch nennen. Außerdem normalerweise. Als ich mich fragte: "Nun, wofür ist es?", Fand ich die folgende Seite.

[Python] Verwendung des Unterstrichs (_) (spezielles Attribut, Dunders)

Demnach anscheinend

――Wenn es eines ist, deutet es nur darauf hin, dass es für den internen Gebrauch bestimmt ist, und der Vorgang ändert sich insbesondere nicht. Es wird jedoch nicht nur geladen, wenn es mit Platzhaltern als Modul aufgerufen wird. --Wenn es zwei gibt, wird der Name entstellt (Namensänderung), so dass Sie nicht so darauf zugreifen können, wie er ist. Es ist jedoch nicht als privat gedacht, sondern wird verwendet, um Namenskonflikte zwischen Klassen mit einer Eltern-Kind-Beziehung zu vermeiden.

Es scheint. Erstens war es seltsam zu erkennen, dass es sich um eine Privatisierung handelte. Dieses Mal habe ich das Programm erstellt, ohne die Klasse zu erben, daher war es ausreichend, einen Unterstrich zu verwenden.

4.) docstring ist eine gute Kultur

Ich wusste irgendwie, dass es auch existiert, aber dies war das erste Mal, dass ich es benutzte. Ich beziehe mich beim Erstellen auf die folgenden Artikel.

[Python] Erfahren Sie, wie Sie eine Dokumentzeichenfolge schreiben, um die Lesbarkeit zu verbessern (NumPy-Stil)

Da dieses Programm für mich selbst entwickelt wurde, schrieb ich es, während ich dachte: "Ist es notwendig?", Aber als Ergebnis "was zu verwenden", "für was" und "was zu tun ist". Es war eine Gelegenheit, fest zu denken. Bis jetzt war es eine Ad-hoc-Methode, um irgendwie mit dem Schreiben zu beginnen, es einmal zu verschieben und dann zu reparieren, aber ich denke, das Schreiben einer Dokumentzeichenfolge hat es ein wenig besser gemacht.

Denkweise

Das Folgende ist der Punkt, den ich empirisch gelernt habe: "Ich denke, das ist besser" als Wissen.

1.) Zu tiefe Datenstrukturen sind out

Als ich anfing, meinen Zeitplan zu organisieren, organisierte ich meine Daten in einem Wörterbuch wie dem folgenden:

python


from datetime import datetime

from datetime import datetime

schedule_dict = {'1week': {datetime(2020, 9, 1) : {datetime(2020, 9, 1, 9, 0): [('Herr Yamada', 'Terada'),('Herr Yoshiki', 'Endo'),],
                                                    datetime(2020, 9, 1, 10, 0): [('Herr Kudo', 'Yamashita'),],},
                            datetime(2020, 9, 2) : {datetime(2020, 9, 2, 10, 0): [('Herr Tsurukawa', 'Honda'),],
                                                    datetime(2020, 9, 2, 11, 0): [('Herr Endo', 'Aizawa'),],},
                            datetime(2020, 9, 2) : {datetime(2020, 9, 3, 9, 0): [('Herr Shimoda', 'Terada'), ('Herr Yoshikawa', 'Goda')],
                                                   }
                           }
                '2week': ....}

Beim Zugriff sieht es so aus.

python


schedule_dict['2week'][datetime(2020, 9, 8)][datetime(2020, 9, 8, 10, 0)]

Die Daten auf der Tabellenkalkulationsseite wurden jede Woche nebeneinander angeordnet, sodass ich an nichts Besonderes dachte, aber sie waren nutzlos tief. Der Zugriff ist immer noch cool, und die Schleifenhierarchie wird immer tiefer, wenn sie bei Verwendung mit einer for-Anweisung erweitert wird.

Immerhin habe ich mitten in der Arbeit Wurzeln geschlagen, den Wochenschlüssel verloren und ihn um eine Stufe flacher gemacht. Wenn ich es noch einmal überprüfe, habe ich das Gefühl, dass ich nicht einmal den 0-Uhr-Datumsschlüssel brauche. Bei Bedarf können Sie auf die Attribute Jahr, Monat und Tag des Typs datetime.datetime zugreifen und diese neu erstellen.

Es wird oft gesagt, dass "nutzlos tiefe Schleifen vermieden werden sollten", aber ich habe gelernt, dass "es auch vermieden werden sollte, nutzlos tiefe Datenschichten zu erstellen", die dies verursachen. Ich habe das Gefühl, dass sich die Belastung pro Prozess jedes Mal verdoppelt **, wenn die Hierarchie vertieft wird. Das Gedächtnis des Gehirns wird hart gesaugt ...

2.) Geben Sie einen anständigen Namen, auch wenn es etwas länger wird

Zu Beginn der Entwicklung wurde der Name, der beim Testen des Teilteils verwendet wurde, wie für den Variablennamen verwendet. Da die Verarbeitung nach dem Ziel klassifiziert wurde, liegt kein Namenskonflikt vor. Ich habe versucht, so kurz wie möglich zu schreiben, z. B. df für Datenrahmen, Datum für Datumsangaben und dct für Wörterbücher.

Ich schlug jedoch sofort gegen die Wand. Es geht mehr um das Gedächtnis des Gehirns als um das Problem mit den Programmspezifikationen. Wenn der Prozess komplizierter wird, "Oh, was ist in diesem Wörterbuch?" "Ich gebe einen Fehler aus, aber ist dieses Datum nicht ein Zeichenfolgentyp?" "Index außerhalb des Bereichs ??? Es gab viele Probleme wie "Ist die Liste nicht die Anzahl der Elemente, die ich hatte?"

Bis jetzt habe ich nur ein Beispielprogramm geschrieben, um die Spezifikationen leicht zu verstehen, also musste ich mir darüber keine Gedanken machen, aber ** der Name sollte angegeben werden, damit er verstanden werden kann, egal wohin er fliegt **. .. In Worten scheint es natürlich zu sein, und ich hatte nicht wirklich darüber nachgedacht.

date_dt für datetime-Datumsangaben, date_str für str-Datumsangaben. Nennen Sie es danach client_salesman_tuples_list, um anzugeben, was gespeichert ist, und verwenden Sie den Namen, der beim Erweitern der for-Anweisung verwendet wird, z. B. für client_salesman_tuple in client_salesman_tuples_list :, wobei Sie sich der Singular- und Pluralform bewusst sind. Ich habs gemacht.

Dank dir ist es etwas einfacher zu verstehen als am Anfang. Erstens wäre es ideal, keine Verarbeitung durchzuführen, die das Gehirn verwirren würde, aber wenn Sie nicht genug Fähigkeiten dafür haben, werden Sie nicht genug sein, und ich möchte daran denken, dass der Name erfunden wird.

3.) Objektorientiert stellt sich ein Regierungsbüro oder eine Firma vor

Ich bin mir nicht sicher, ob das wirklich richtig ist. Vor ungefähr zwei Wochen, als ich es vom Teil zum Ganzen zusammensetzte, schrieb ich ungefähr 100 Zeilen flach und kehrte zu mir selbst zurück. Es wäre eine große Sache, wenn es in diesem Zustand wäre. Ich habe eine kleine Offenbarung von der folgenden Seite erhalten, die nach ein wenig Recherche herauskam.

Was ist ein Namespace?

Ich bin der Meinung, dass die Objektorientierung die Aufgabe ist, den Namespace selbst richtig durch die Klasse zu unterteilen.

Ich war eine Weile verblüfft, als ich das Wort "angemessene Aufteilung" sah, aber plötzlich kam mir die Idee "** Ist das nicht dasselbe wie ein Regierungsbüro? **".

Vor einiger Zeit musste ich zum Rathaus gehen, um eine Aufenthaltskarte zu bekommen und eine Weile warten. Während ich wartete, schaute ich ohne Grund auf das Gelände des Regierungsbüros, aber es war wirklich fein aufgeteilt. Bürger, Wirtschafts- und Industrietourismus, Bauwesen, Stadtplanung etc etc ... Auf den ersten Blick denken manche Leute vielleicht: "Sind Bau und Stadtplanung nicht gleich?", Aber in Wirklichkeit sind sie durch den Abschnitt △△ der Abteilung ○○ unterteilt. Ich kenne den Inhalt der Arbeit nicht, aber es scheint, dass sie gut geteilt werden. Dies ist dasselbe wie "** Klassifizierung **".

Gelegentlich kann eine Zusammenarbeit mit den Abteilungen erforderlich sein, es werden jedoch nicht alle Informationen weitergegeben. Papier und Daten werden überflutet. Es ist sinnvoll, dass die verantwortliche Person so viele Informationen mitbringt und bespricht, wie für den Job benötigt werden. Dies ist dasselbe wie "** Aus Vererbung synthetisieren **".

Außerdem weiß "ich", der die Karte des Bewohners beantragt hat, nicht, welche Art von Verarbeitung im Inneren erfolgt. Ich kann mir vorstellen, dass die verantwortliche Person die Dokumente durch Eingabe verschiedener Dinge auf dem Computer ausfüllt, aber ich schreibe nur das Antragsformular und bezahle es. Dann können Sie die Aufenthaltsbescheinigung problemlos erhalten. Vielleicht wissen sogar diejenigen, die am Schalter arbeiten, nicht alles darüber, wofür die speziell geschriebenen Dokumente und die eingegebenen Daten verwendet werden und wie sie gespeichert werden. Dies ist dasselbe wie "** Informationen verstecken **".

Mit diesem Gefühl gelang es mir, ein Regierungsbüro zu klassifizieren, als ich es mir vorstellte. Selbst wenn ich es selbst schreibe, bin ich mir nicht sicher, ob es wirklich zu diesem Verständnis passt, aber ich konnte es gekrümmt schreiben, also bin ich vorläufig in Ordnung.

Ich dachte, Qiita hätte einen aktuellen Artikel. Ich denke, dies ist eine viel einfachere Erklärung. Bitte beziehen Sie sich darauf.

Objektorientiertes Designrezept eines objektorientierten Onkels mit 25 Jahren objektorientierter Geschichte

Ich möchte hier in Zukunft lernen

Schließlich werde ich schreiben, dass ich einige Kenntnisse und Ideen hatte, aber ich konnte es doch nicht gut gebrauchen.

Verwendung von itertools, um Aussagen flach zu machen

Ich wusste es nicht noch einmal, aber es gibt eine Bibliothek namens itertools in der Standard-Python-Bibliothek. Eine leicht verständliche Erklärung finden Sie in diesem Beitrag. Ich habe mich hier jedoch auf die Produktmethode in itertools konzentriert.

Dieses Produkt erzeugt eine Ausgabe ähnlich einer typischen Mehrfachschleife, wie in der offiziellen Dokumentation (https://docs.python.org/3/library/itertools.html#itertools.product) beschrieben. Werde dir geben.

python


import itertools

section_list = ['Section1', 'Section2', 'Section3']
time_list = ['9:00', '10:00', '11:00']

for section in section_list:
    for time in time_list:
        print(section, time)

print("------------")
        
for section, time in list(itertools.product(section_list, time_list)):
    print(section, time)

Die Ausgabe ist die gleiche.

Section1 9:00
Section1 10:00
Section1 11:00
Section2 9:00
Section2 10:00
Section2 11:00
Section3 9:00
Section3 10:00
Section3 11:00
------------
Section1 9:00
Section1 10:00
Section1 11:00
Section2 9:00
Section2 10:00
Section2 11:00
Section3 9:00
Section3 10:00
Section3 11:00

Sie können es auch als Taple erhalten.

python


for tpl in list(itertools.product(section_list, time_list)):
    print(tpl)
('Section1', '9:00')
('Section1', '10:00')
('Section1', '11:00')
('Section2', '9:00')
('Section2', '10:00')
('Section2', '11:00')
('Section3', '9:00')
('Section3', '10:00')
('Section3', '11:00')

Ich wollte dies wirklich nutzen, um die Schleifenhierarchie zu reduzieren, aber es hat nicht funktioniert. Wie oben erwähnt, habe ich schmerzlich verstanden, dass eine Erhöhung der Schleifenhierarchie direkt zu einer Erhöhung der Belastung des Gehirns führt. Daher möchte ich in Zukunft sowohl itertools als auch die Idee der Datenstruktur verwenden.

Zusammenfassung

Als Ratschlag für Programmieranfänger höre ich oft "Warum versuchst du nicht, vorerst etwas zu machen?", Aber ich verstehe, dass dies wirklich ein vernünftiger Rat ist. Ich hatte es ungefähr zehnmal so schwer, wie ich es mir vorgestellt hatte, aber ich habe das Gefühl, dass ich viele Dinge habe.

Wenn Sie Meinungen oder Ratschläge haben, hinterlassen Sie diese bitte im Kommentarbereich.

Recommended Posts

Entwicklungsmemorandum ~ Pandas, Prognose, Datenstruktur ~
Memorandum of Pandas
Pandas Memorandum
Pandas Daten lesen
Pandas Operations Memorandum
[Zur Aufnahme] Pandas Memorandum
Datenvisualisierung mit Pandas
Datenmanipulation mit Pandas!
Daten mit Pandas mischen
[Python-Tutorial] Datenstruktur
Datenstruktur Python Push Pop
Datenverarbeitung 3 (Entwicklung) Informationen zum Datenformat
Memorandum (Pseudo-Vlookup von Pandas)
Memorandum @ Python ODER Seminar: Pandas
Datenanalyse mit Python-Pandas
Datenverarbeitungstipps mit Pandas