Praxis der Datenanalyse durch Python und Pandas (Tokyo COVID-19 Data Edition)

Einführung

Jedes Mal, wenn ich die Nachrichten über die Anzahl neuer Koronavirusinfektionen sah, dachte ich: "Ich möchte, dass Sie mir mehr über die Aufteilung der Altersgruppe erzählen", aber ich erfuhr, dass die Stadtregierung von Tokio Daten über positive Patienten veröffentlicht hat. ..

Hier werden wir vorstellen, wie die von der Stadtregierung von Tokio veröffentlichten Daten mit Python und Pandas, Seaborn, Matplotlib, analysiert und visualisiert werden.

Der Hauptpunkt dieses Artikels sind nicht die Vorhersagen und Empfehlungen, dass "dies in Zukunft geschehen wird" und "diese Art von Maßnahmen ergriffen werden sollten", sondern "dies erleichtert die Visualisierung der Daten, sodass jeder sie ausprobieren sollte". Wenn Sie es selbst versuchen, werden Sie Ihr Verständnis vertiefen. Probieren Sie es also aus.

Beachten Sie, dass Matplotlib, wenn Sie sich besonders mit Details wie dem Diagrammlayout und dem Achsenformat befassen, eine mühsame Verarbeitung erfordert, sodass ich hier nicht auf Details eingehen werde (nur eine kleine Berührung am Ende). Anstatt ein ansprechendes Diagramm für eine umfassende Offenlegung zu erstellen, besteht das Ziel darin, die Daten zu visualisieren und Trends selbst zu erkennen.

Beispielcode ist auch auf GitHub verfügbar. Das Jupyter-Notizbuch (.ipynb) ist leichter zu lesen, lesen Sie es daher ebenfalls.

Datenübersicht

Tokio

Die positiven Patientendaten für Tokio werden unten veröffentlicht.

Sie erreichen es über den Link "Get open data" auf Tokios neuer Website zur Kontrolle von Koronavireninfektionen.

Mit Blick auf Verlauf scheint es, dass es an Wochentagen von 10 auf 15 Uhr aktualisiert wird.

Andere Präfekturen

Nachfolgend finden Sie eine Liste der Websites, die die Websites für Gegenmaßnahmen in Tokio gegabelt haben.

Einige Websites, wie z. B. Tokio, enthalten Links zu offenen Daten. Nachfolgend finden Sie Beispiele aus den Präfekturen Hokkaido und Kanagawa.

Selbst wenn auf der Website kein Link vorhanden ist, sollten die Daten selbst irgendwo veröffentlicht werden, damit Sie sie durch Suchen finden können.

Der folgende Beispielcode verwendet Daten aus Tokio. Daten anderer Präfekturen können unterschiedliche Elemente haben, aber die Grundbehandlung ist dieselbe.

Andere Daten

Darüber hinaus gibt es als Daten zum neuen Coronavirus aggregierte Daten wie die Anzahl der durchgeführten inländischen PCR-Tests, die Anzahl der positiven Ergebnisse, die Anzahl der im Krankenhaus befindlichen Personen und die Anzahl der vom Ministerium für Gesundheit, Arbeit und Soziales angekündigten Todesfälle.

Bibliotheksversion

Die Versionen jeder Bibliothek und von Python selbst im folgenden Beispielcode lauten wie folgt. Beachten Sie, dass sich verschiedene Versionen möglicherweise unterschiedlich verhalten.

import math
import sys

import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns

print(pd.__version__)
# 1.0.5

print(mpl.__version__)
# 3.3.0

print(sns.__version__)
# 0.10.1

print(sys.version)
# 3.8.5 (default, Jul 21 2020, 10:48:26) 
# [Clang 11.0.3 (clang-1103.0.32.62)]

Datenbestätigung und Vorverarbeitung

Geben Sie den Pfad zur heruntergeladenen CSV-Datei in "pd.read_csv ()" an und lesen Sie ihn als "DataFrame". Als Beispiel dienen die Daten bis zum 31. Juli 2020.

df = pd.read_csv('data/130001_tokyo_covid19_patients_20200731.csv')

Sie können die URL direkt im Argument von "pd.read_csv ()" angeben, aber es ist sicherer, sie lokal herunterzuladen, da in der Phase von Versuch und Irrtum mehrmals vergeblich darauf zugegriffen wird.

# df = pd.read_csv('https://stopcovid19.metro.tokyo.lg.jp/data/130001_tokyo_covid19_patients.csv')

Die Anzahl der Zeilen / Spalten und die Daten am Anfang und Ende sind wie folgt.

print(df.shape)
# (12691, 16)

print(df.head())
#Nein Nationaler Code der öffentlichen Organisation Präfekturname Stadtbezirk Name der Stadt / des Dorfes veröffentlicht_Datumsbeginn_Datum Patient_Wohnort Patient_Alter Patient_Sex\
#0 1 130001 Tokyo NaN 2020-01-24 Fr NaN Wuhan City, Provinz Hubei Männlich in seinen 40ern
#1 2 130001 Tokyo NaN 2020-01-25 Sa NaN Wuhan City, Provinz Hubei Frauen in den Dreißigern
#2 3 130001 Tokyo NaN 2020-01-30 Do NaN Changsha Stadt, Provinz Hunan Frauen in ihren 30ern
#3 4 130001 Tokyo NaN 2020-02-13 Do NaN Männlich in seinen 70ern in Tokio
#4 5 130001 Tokyo NaN 2020-02-14 Fr NaN Frauen in den Fünfzigern in Tokio
# 
#geduldig_Attribut Patient_Zustand Patient_Symptompatient_Reiseverlaufsflagge Bemerkungen Entladene Flagge
# 0    NaN    NaN    NaN           NaN NaN     1.0  
# 1    NaN    NaN    NaN           NaN NaN     1.0  
# 2    NaN    NaN    NaN           NaN NaN     1.0  
# 3    NaN    NaN    NaN           NaN NaN     1.0  
# 4    NaN    NaN    NaN           NaN NaN     1.0  

print(df.tail())
#Nein Nationaler Code der öffentlichen Organisation Präfekturname Stadtbezirk Name der Stadt / des Dorfes veröffentlicht_Datumsbeginn_Datum Patient_Wohnort Patient_Alter\
#12686 12532 130001 Tokyo NaN 2020-07-31 Fr NaN NaN 70er Jahre
#12687 12558 130001 Tokyo NaN 2020-07-31 Fr NaN NaN 70er Jahre
#12688 12563 130001 Tokyo NaN 2020-07-31 Fr NaN NaN 70er Jahre
#12689 12144 130001 Tokyo NaN 2020-07-31 Fr NaN NaN 80er Jahre
#12690 12517 130001 Tokyo NaN 2020-07-31 Fr NaN NaN 80er Jahre
# 
#geduldig_Geschlechtspatientin_Attribut Patient_Zustand Patient_Symptompatient_Reiseverlaufsflagge Bemerkungen Entladene Flagge
#12686 Männliches NaN NaN NaN NaN NaN NaN
#12687 Männliches NaN NaN NaN NaN NaN NaN
#12688 Männliches NaN NaN NaN NaN NaN NaN
#12689 Weibliches NaN NaN NaN NaN NaN NaN NaN
#12690 Männliches NaN NaN NaN NaN NaN NaN

Wenn kategoriale Daten wie diese die Hauptdaten sind, können Sie sich mithilfe von Methoden wie "count ()", "nunique ()", "unique ()" und "value_counts ()" leicht einen Überblick verschaffen.

count () gibt die Anzahl der Elemente zurück, bei denen es sich nicht um den fehlenden Wert NaN handelt. Es ist ersichtlich, dass detaillierte Informationen wie Namen, Symptome und Attribute von Stadt / Gemeinde / Stadt / Dorf nicht bekannt gegeben werden (keine Daten), wahrscheinlich aus Gründen des Datenschutzes.

print(df.count())
# No              12691
#National Local Public Organization Code 12691
#Präfekturname 12691
#Name der Stadt 0
#Veröffentlicht_Datum 12691
#Tag 12691
#Beginn_Datum 0
#geduldig_Wohnort 12228
#geduldig_Alter 12691
#geduldig_Geschlecht 12691
#geduldig_Attribut 0
#geduldig_Zustand 0
#geduldig_Symptom 0
#geduldig_Reiseverlauf Flagge 0
#Bemerkung 0
#Entladene Flagge 7186
# dtype: int64

nunique () gibt die Anzahl der Datentypen zurück. Da es sich um die Daten von Tokio handelt, sind der nationale Kommunalcode und der Name der Präfektur alle gleich.

print(df.nunique())
# No              12691
#Nationaler Code der lokalen öffentlichen Organisation 1
#Präfekturname 1
#Name der Stadt 0
#Veröffentlicht_Datum 164
#Tag 7
#Beginn_Datum 0
#geduldig_Wohnort 8
#geduldig_Alter 13
#geduldig_Geschlecht 5
#geduldig_Attribut 0
#geduldig_Zustand 0
#geduldig_Symptom 0
#geduldig_Reiseverlauf Flagge 0
#Bemerkung 0
#Entladene Flagge 1
# dtype: int64

Für jede Spalte (= Serie) können Sie die eindeutigen Elemente und ihre Anzahl (Auftrittshäufigkeit) mit unique (), value_counts () überprüfen.

print(df['geduldig_Residenz'].unique())
# ['Stadt Wuhan, Provinz Hubei' 'Stadt Changsha, Provinz Hunan' 'In Tokio' 'Ausserhalb der Stadt' '―' 'Nachforschungen anstellen' '-' "'-" nan]

print(df['geduldig_Residenz'].value_counts(dropna=False))
#Tokio 11271
#Außerhalb von Tokio 531
# NaN         463
# ―           336
#In Untersuchung 85
#Stadt Wuhan, Provinz Hubei 2
#Stadt Changsha, Provinz Hunan 1
# '-            1
# -             1
# Name:geduldig_Residenz, dtype: int64

print(df['geduldig_Sex'].unique())
# ['männlich' 'Weiblich' "'-" '―' 'Unbekannt']

print(df['geduldig_Sex'].value_counts())
#Männlich 7550
#Weiblich 5132
# '-       7
#Unbekannt 1
# ―        1
# Name:geduldig_Sex, dtype: int64

Dieses Mal werden wir das Analyseziel auf das Veröffentlichungsdatum, das Alter des Patienten und die entlassene Flagge eingrenzen. Ändern Sie der Einfachheit halber den Spaltennamen mit "rename ()".

df = df[['Veröffentlicht_Datum', 'geduldig_Alter', 'Entladene Flagge']].copy()

df.rename(columns={'Veröffentlicht_Datum': 'date_str', 'geduldig_Alter': 'age_org', 'Entladene Flagge': 'discharged'},
          inplace=True)

print(df)
#          date_str age_org  discharged
# 0      2020-01-24 40s 1.0
# 1      2020-01-25 30s 1.0
# 2      2020-01-30 30s 1.0
# 3      2020-02-13 70er Jahre 1.0
# 4      2020-02-14 50er Jahre 1.0
# ...           ...     ...         ...
# 12686  2020-07-31 70s NaN
# 12687  2020-07-31 70s NaN
# 12688  2020-07-31 70s NaN
# 12689  2020-07-31 80er NaN
# 12690  2020-07-31 80er NaN
# 
# [12691 rows x 3 columns]

Der Grund für die Verwendung von "copy ()" hier ist, "SettingWithCopyWarning" zu verhindern. In diesem Fall werden die Daten nicht aktualisiert, sodass es kein Problem gibt, wenn Sie sie in Ruhe lassen.

In der Ära-Spalte enthält sie Daten wie "unbekannt" und "-".

print(df['age_org'].unique())
# ['Vierziger Jahre' '30er Jahre' '70er Jahre' '50er Jahre' '60er Jahre' '80er Jahre' '20er Jahre' 'Unter 10 Jahren' '90er Jahre' '10er' '100 Jahre und älter'
#  'Unbekannt' "'-"]

print(df['age_org'].value_counts())
#20s 4166
#30s 2714
#40er Jahre 1741
#50er Jahre 1362
#60er Jahre 832
#70er Jahre 713
#80er 455
#Teen 281
#90er Jahre 214
#Unter 10 Jahren 200
#Unbekannt 6
#100 Jahre und älter 5
# '-           2
# Name: age_org, dtype: int64

Da die Anzahl klein ist, werde ich sie hier ausschließen.

df = df[~df['age_org'].isin(['Unbekannt', "'-"])]

print(df)
#          date_str age_org  discharged
# 0      2020-01-24 40s 1.0
# 1      2020-01-25 30s 1.0
# 2      2020-01-30 30s 1.0
# 3      2020-02-13 70er Jahre 1.0
# 4      2020-02-14 50er Jahre 1.0
# ...           ...     ...         ...
# 12686  2020-07-31 70s NaN
# 12687  2020-07-31 70s NaN
# 12688  2020-07-31 70s NaN
# 12689  2020-07-31 80er NaN
# 12690  2020-07-31 80er NaN
# 
# [12683 rows x 3 columns]

print(df['age_org'].unique())
# ['Vierziger Jahre' '30er Jahre' '70er Jahre' '50er Jahre' '60er Jahre' '80er Jahre' '20er Jahre' 'Unter 10 Jahren' '90er Jahre' '10er' '100 Jahre und älter']

Da die Alterseinteilung in Ordnung ist, machen Sie es etwas rauer. Die gesamte rechte Seite ist in Klammern "()" eingeschlossen, da sie in der Mitte bricht.

df['age'] = (
    df['age_org'].replace(['Unter 10 Jahren', '10er'], '0-19')
    .replace(['20er Jahre', '30er Jahre'], '20-39')
    .replace(['Vierziger Jahre', '50er Jahre'], '40-59')
    .replace(['60er Jahre', '70er Jahre', '80er Jahre', '90er Jahre', '100 Jahre und älter'], '60-')
)

print(df['age'].unique())
# ['40-59' '20-39' '60-' '0-19']

print(df['age'].value_counts())
# 20-39    6880
# 40-59    3103
# 60-      2219
# 0-19      481
# Name: age, dtype: int64

Die Spalte "Datum und Uhrzeit" (Veröffentlichungsdatum) "date_str" ist eine Zeichenfolge. Fügen Sie für die zukünftige Verarbeitung die Spalte "Datum" hinzu, die in den Typ "datetime64 [ns]" konvertiert wurde.

df['date'] = pd.to_datetime(df['date_str'])

print(df.dtypes)
# date_str              object
# age_org               object
# discharged           float64
# age                   object
# date          datetime64[ns]
# dtype: object

Dies ist das Ende der Vorverarbeitung. Von hier aus wird ein Beispiel für die tatsächliche Analyse und Visualisierung von Daten gezeigt.

Veränderungen in der Anzahl neuer positiver Patienten nach Altersgruppen

Hier betrachten wir Veränderungen in der Anzahl neuer positiver Patienten nach Altersgruppen. Die Gesamtzahl der neuen positiven Patienten wird am Ende als Beispiel für die Verarbeitung mit Matplotlib beschrieben.

Gestapeltes Balkendiagramm

Verwenden Sie pd.crosstab (), um Datum und Uhrzeit (Veröffentlichungsdatum) und Alter zu kreuzen.

df_ct = pd.crosstab(df['date'], df['age'])

print(df_ct)
# age         0-19  20-39  40-59  60-
# date                               
# 2020-01-24     0      0      1    0
# 2020-01-25     0      1      0    0
# 2020-01-30     0      1      0    0
# 2020-02-13     0      0      0    1
# 2020-02-14     0      0      1    1
# ...          ...    ...    ...  ...
# 2020-07-27     5     79     34   13
# 2020-07-28    13    168     65   20
# 2020-07-29     9    160     56   25
# 2020-07-30    11    236     83   37
# 2020-07-31    10    332     82   39
# 
# [164 rows x 4 columns]

print(type(df_ct.index))
# <class 'pandas.core.indexes.datetimes.DatetimeIndex'>

Die in den Typ "datetime64 [ns]" konvertierte Spalte wird zu einem neuen Index und wird als "DatetimeIndex" behandelt. Beachten Sie, dass selbst wenn die Ausgabe identisch ist und Sie einen Zeichenfolgentyp mit Datum und Uhrzeit angeben, dies nicht "DatetimeIndex" ist.

Wöchentlich mit resample () aggregieren. resample () kann nur mit DatetimeIndex ausgeführt werden.

df_ct_week = df_ct.resample('W', label='left').sum()

print(df_ct_week)
# age         0-19  20-39  40-59  60-
# date                               
# 2020-01-19     0      1      1    0
# 2020-01-26     0      1      0    0
# 2020-02-02     0      0      0    0
# 2020-02-09     0      2      5    9
# 2020-02-16     0      1      3    6
# 2020-02-23     0      2      3    5
# 2020-03-01     2      5      9    9
# 2020-03-08     0      5     10   11
# 2020-03-15     0     10     27   12
# 2020-03-22     7    100     88  102
# 2020-03-29    16    244    198  148
# 2020-04-05    21    421    369  271
# 2020-04-12    30    350    375  280
# 2020-04-19    32    286    267  264
# 2020-04-26    29    216    165  260
# 2020-05-03     7    105     69  120
# 2020-05-10     2     46     16   46
# 2020-05-17     3     22     10   15
# 2020-05-24     4     43     16   21
# 2020-05-31     2     89     34   22
# 2020-06-07     5    113     17   26
# 2020-06-14     6    177     29   28
# 2020-06-21    10    236     65   23
# 2020-06-28    34    460    107   51
# 2020-07-05    79    824    191   68
# 2020-07-12    66   1006    295  117
# 2020-07-19    78   1140    414  171
# 2020-07-26    48    975    320  134

Visualisiert mit plot (). Sie können ganz einfach ein gestapeltes Balkendiagramm erstellen.

df_ct_week[:-1].plot.bar(stacked=True)

bar_ct_week.png

Die Daten in der letzten Zeile (letzte Woche) werden durch "[: -1]" ausgeschlossen. Diese Daten schließen die letzte Woche aus, da sie den Samstag (1. August 2020) nicht enthalten und nicht zum Vergleich mit anderen Wochen geeignet sind.

Das Jupyter-Notizbuch zeigt das Diagramm in der Ausgabezelle an. Wenn Sie es als Bilddatei speichern möchten, verwenden Sie plt.savefig (). Sie können auch mit der rechten Maustaste klicken, um die Ausgabe des Jupyter-Notizbuchs zu speichern.

plt.figure()
df_ct_week[:-1].plot.bar(stacked=True)
plt.savefig('image/bar_chart.png', bbox_inches='tight')
plt.close('all')

Der Zustand des Auftretens ist unbekannt, aber es gab ein Problem, dass die Beschriftung der X-Achse beim Speichern abgeschnitten wurde. Beziehen Sie sich auf Folgendes und setzen Sie "bbox_inches =" tight ", um das Problem zu lösen.

Wenn Sie ein Balkendiagramm wie im obigen Beispiel erstellen, wird die Uhrzeit auf der Beschriftung der X-Achse angezeigt. Die einfachste Lösung besteht darin, den Index in eine Zeichenfolge in einem beliebigen Format zu konvertieren.

df_ct_week_str = df_ct_week.copy()
df_ct_week_str.index = df_ct_week_str.index.strftime('%Y-%m-%d')

df_ct_week_str[:-1].plot.bar(stacked=True, figsize=(8, 4))

bar_ct_week_str.png

Standardisieren Sie das Ganze und sehen Sie den Übergang des Altersverhältnisses. T ist die Translokation (Zeilen und Spalten tauschen). Sie kann standardisiert werden, indem Sie sie transponieren, durch den Gesamtwert dividieren, erneut verschieben und auf den ursprünglichen Wert zurücksetzen.

Die meisten jungen Menschen (20-30 Jahre) haben seit Juni geschlossen, aber in letzter Zeit steigt der Anteil der Menschen mittleren Alters (40 Jahre und älter).

df_ct_week_str_norm = (df_ct_week_str.T / df_ct_week_str.sum(axis=1)).T

bar_ct_week_str_norm.png

Die Veränderungen zwischen jungen Menschen (20-30 Jahre) und älteren Menschen (60 Jahre und darüber hinaus) sind wie folgt. Auch die absolute Zahl älterer Menschen ist Ende März auf das Niveau gestiegen.

df_ct_week_str[:-1][['20-39', '60-']].plot.bar(figsize=(8, 4))

bar_ct_week_str_young_old.png

Diagramm mit unterbrochener Linie (im Vergleich zur Vorwoche)

Berechnen Sie die Veränderung gegenüber der Vorwoche, um den Impuls der Ausbreitung der Infektion zu sehen.

Die Daten können durch "shift ()" verschoben und geteilt werden.

df_week_ratio = df_ct_week / df_ct_week.shift()

print(df_week_ratio)
# age             0-19      20-39     40-59       60-
# date                                               
# 2020-01-19       NaN        NaN       NaN       NaN
# 2020-01-26       NaN   1.000000  0.000000       NaN
# 2020-02-02       NaN   0.000000       NaN       NaN
# 2020-02-09       NaN        inf       inf       inf
# 2020-02-16       NaN   0.500000  0.600000  0.666667
# 2020-02-23       NaN   2.000000  1.000000  0.833333
# 2020-03-01       inf   2.500000  3.000000  1.800000
# 2020-03-08  0.000000   1.000000  1.111111  1.222222
# 2020-03-15       NaN   2.000000  2.700000  1.090909
# 2020-03-22       inf  10.000000  3.259259  8.500000
# 2020-03-29  2.285714   2.440000  2.250000  1.450980
# 2020-04-05  1.312500   1.725410  1.863636  1.831081
# 2020-04-12  1.428571   0.831354  1.016260  1.033210
# 2020-04-19  1.066667   0.817143  0.712000  0.942857
# 2020-04-26  0.906250   0.755245  0.617978  0.984848
# 2020-05-03  0.241379   0.486111  0.418182  0.461538
# 2020-05-10  0.285714   0.438095  0.231884  0.383333
# 2020-05-17  1.500000   0.478261  0.625000  0.326087
# 2020-05-24  1.333333   1.954545  1.600000  1.400000
# 2020-05-31  0.500000   2.069767  2.125000  1.047619
# 2020-06-07  2.500000   1.269663  0.500000  1.181818
# 2020-06-14  1.200000   1.566372  1.705882  1.076923
# 2020-06-21  1.666667   1.333333  2.241379  0.821429
# 2020-06-28  3.400000   1.949153  1.646154  2.217391
# 2020-07-05  2.323529   1.791304  1.785047  1.333333
# 2020-07-12  0.835443   1.220874  1.544503  1.720588
# 2020-07-19  1.181818   1.133201  1.403390  1.461538
# 2020-07-26  0.615385   0.855263  0.772947  0.783626

df_week_ratio['2020-05-03':'2020-07-25'].plot(grid=True)

line_week_ratio.png

Im Juli ist die wöchentliche Rate in jeder Altersgruppe gesunken.

Im Gegensatz zum Balkendiagramm werden beim Erstellen eines Liniendiagramms mit "plot ()" (oder "plot.line ()") die Datums- und Zeitdaten auf der X-Achse wie im obigen Beispiel entsprechend formatiert. Beachten Sie, dass es abhängig vom Inhalt der Datums- und Zeitdaten, wie später beschrieben, möglicherweise nicht formatiert wird.

Wärmekarte

Erstellen Sie eine Heatmap als weiteren Ansatz, um den Übergang der Anzahl neuer positiver Patienten nach Altersgruppen zu erfassen.

Hier wird die detaillierte Altersgruppe unverändert verwendet. Kreuztabelle mit pd.crosstab () wie im Beispiel des gestapelten Balkendiagramms. Da "resample ()" nicht verwendet wird, werden Datum und Uhrzeit "date_str" des Zeichenkettentyps angegeben. Die horizontale Achse wird mit "T" transponiert, um Datum und Uhrzeit einzustellen, und die untere Seite der vertikalen Achse wird mit "[:: -1]" transponiert, um die Reihenfolge der Zeilen nach der Translokation umzukehren.

df['age_detail'] = df['age_org'].replace(
    {'Unter 10 Jahren': '0-9', '10er': '10-19', '20er Jahre': '20-29', '30er Jahre': '30-39', 'Vierziger Jahre': '40-49', '50er Jahre': '50-59',
     '60er Jahre': '60-69', '70er Jahre': '70-79', '80er Jahre': '80-89', '90er Jahre': '90-', '100 Jahre und älter': '90-'}
)

df_ct_hm = pd.crosstab(df['date_str'], df['age_detail']).T[::-1]

Die Seaborn-Funktion "Heatmap ()" ist nützlich zum Erstellen von Heatmaps.

plt.figure(figsize=(15, 5))
sns.heatmap(df_ct_hm, cmap='hot')

heatmap.png

Es kann bestätigt werden, dass sich die Infektion seit Juni allmählich auf ältere Menschen ausgeweitet hat.

Siehe unten für logarithmische Wärmekarten. Ich habe eine Warnung bekommen, aber es hat vorerst funktioniert.

Beachten Sie, dass, wenn die Daten "0" enthalten, ein Fehler auftritt, sodass der grobe Vorgang des Ersetzens von "0" durch "0,1" ausgeführt wird.

df_ct_hm_re = df_ct_hm.replace({0: 0.1})

min_value = df_ct_hm_re.values.min()
max_value = df_ct_hm_re.values.max()

log_norm = mpl.colors.LogNorm(vmin=min_value, vmax=max_value)
cbar_ticks = [math.pow(10, i) for i in range(math.floor(math.log10(min_value)),
                                             1 + math.ceil(math.log10(max_value)))]

plt.figure(figsize=(15, 5))
sns.heatmap(df_ct_hm_re, norm=log_norm, cbar_kws={"ticks": cbar_ticks})

heatmap_log.png

Übrigens habe ich die Idee der Visualisierung mit einer Heatmap anhand des Beispiels von Florida im folgenden Artikel gelernt.

@Zorinaq, der das Florida-Diagramm erstellt hat, hat den Code veröffentlicht, um zusätzlich zur Heatmap verschiedene Diagramme wie zukünftige Prognosen zu erstellen. Ohne Python-Kenntnisse scheint es schwierig zu sein, aber wenn Sie interessiert sind, sollten Sie einen Blick darauf werfen.

Entladene Flagge

wichtiger Punkt

Wie aus dem oben gezeigten Ergebnis von "count ()" hervorgeht, gibt es 7186 Fälle, in denen die entladene Flagge in den öffentlichen Daten "1" ist, aber [New Coronavirus Infectious Disease Control Site in Tokio](https: / /stopcovid19.metro.tokyo.lg.jp/) "Entlassung usw. (einschließlich des Ablaufs der medizinischen Behandlungsdauer)" beträgt 9615 (Stand 31. Juli 2020, Aktualisierung 20:30).

tokyo_stopcovid.png

Ich weiß nicht, ob sich die Reflexion der Daten nur verzögert oder aus irgendeinem Grund, aber bitte beachten Sie, dass die entladene Flagge der öffentlichen Daten von der aktuellen Situation abweichen kann.

Gestapeltes Balkendiagramm

Ähnlich wie beim Beispiel des Übergangs der Anzahl positiver Personen nach Altersgruppen wird der Übergang der entladenen Flagge in einem gestapelten Balkendiagramm angezeigt. Der fehlende Wert "NaN" wird als Vorverarbeitung durch "0" ersetzt.

print(df['discharged'].unique())
# [ 1. nan]

df['discharged'] = df['discharged'].fillna(0).astype('int')

print(df['discharged'].unique())
# [1 0]

print(pd.crosstab(df['date'], df['discharged']).resample('W', label='left').sum()[:-1].plot.bar(stacked=True))

bar_discharged_all.png

Wenn Sie Bedenken haben, dass die Uhrzeit auf der X-Achse angezeigt wird, können Sie Datum und Uhrzeit des Index in eine Zeichenfolge konvertieren, wie im Beispiel für Änderungen der Anzahl der Positiven nach Altersgruppen. Ich lasse es hier. Gleiches gilt für die folgenden Beispiele.

Diese Grafik zeigt den Prozentsatz der entladenen Flags nach Veröffentlichungsdatum. Natürlich wurden viele der Personen, die lange Zeit als positiv bestätigt wurden (= das Datum der Veröffentlichung ist alt), entlassen (= die entlassene Flagge ist "1").

Nach Altersgruppe prüfen. Wenn Sie in pd.crosstab () mehrere Spalten in der Liste angeben, wird das Ergebnis als Multi-Index erhalten.

df_dc = pd.crosstab(df['date'], [df['age'], df['discharged']]).resample('W', label='left').sum()

print(df_dc)
# age        0-19     20-39      40-59       60-     
# discharged    0   1     0    1     0    1    0    1
# date                                               
# 2020-01-19    0   0     0    1     0    1    0    0
# 2020-01-26    0   0     0    1     0    0    0    0
# 2020-02-02    0   0     0    0     0    0    0    0
# 2020-02-09    0   0     0    2     0    5    0    9
# 2020-02-16    0   0     0    1     0    3    0    6
# 2020-02-23    0   0     0    2     0    3    0    5
# 2020-03-01    0   2     0    5     0    9    0    9
# 2020-03-08    0   0     0    5     0   10    1   10
# 2020-03-15    0   0     0   10     0   27    0   12
# 2020-03-22    0   7     0  100     0   88    2  100
# 2020-03-29    0  16     1  243     4  194    9  139
# 2020-04-05    0  21     5  416     1  368   11  260
# 2020-04-12    1  29     0  350     6  369   10  270
# 2020-04-19    2  30     3  283     6  261   17  247
# 2020-04-26    1  28     8  208     4  161   33  227
# 2020-05-03    1   6     6   99     5   64   23   97
# 2020-05-10    0   2     7   39     3   13    8   38
# 2020-05-17    2   1    10   12     2    8    9    6
# 2020-05-24    3   1    18   25     8    8    5   16
# 2020-05-31    0   2    13   76     8   26    9   13
# 2020-06-07    1   4    17   96     7   10   12   14
# 2020-06-14    3   3    84   93    13   16   17   11
# 2020-06-21    4   6    75  161    18   47    8   15
# 2020-06-28    4  30    37  423    19   88   20   31
# 2020-07-05   44  35   211  613    92   99   46   22
# 2020-07-12   62   4   803  203   250   45  113    4
# 2020-07-19   78   0  1140    0   414    0  171    0
# 2020-07-26   48   0   975    0   320    0  134    0

Die Grafiken von jungen und älteren Menschen sind wie folgt.

df_dc[:-1]['20-39'].plot.bar(stacked=True)

bar_discharged_young.png

df_dc[:-1]['60-'].plot.bar(stacked=True)

bar_discharged_old.png

Wie Sie sich vorstellen können, ist der Prozentsatz älterer Menschen, deren Entlassungsdatum nicht auf "1" festgelegt ist, höher, selbst wenn das Veröffentlichungsdatum älter ist, und es scheint, dass die Krankenhauseinweisung mit größerer Wahrscheinlichkeit verlängert wird.

Standardisieren, um das Verhältnis besser sichtbar zu machen.

x_young = df_dc[9:-1]['20-39']
x_young_norm = (x_young.T / x_young.sum(axis=1)).T

print(x_young_norm)
# discharged         0         1
# date                          
# 2020-03-22  0.000000  1.000000
# 2020-03-29  0.004098  0.995902
# 2020-04-05  0.011876  0.988124
# 2020-04-12  0.000000  1.000000
# 2020-04-19  0.010490  0.989510
# 2020-04-26  0.037037  0.962963
# 2020-05-03  0.057143  0.942857
# 2020-05-10  0.152174  0.847826
# 2020-05-17  0.454545  0.545455
# 2020-05-24  0.418605  0.581395
# 2020-05-31  0.146067  0.853933
# 2020-06-07  0.150442  0.849558
# 2020-06-14  0.474576  0.525424
# 2020-06-21  0.317797  0.682203
# 2020-06-28  0.080435  0.919565
# 2020-07-05  0.256068  0.743932
# 2020-07-12  0.798211  0.201789
# 2020-07-19  1.000000  0.000000

x_young_norm.plot.bar(stacked=True)

bar_discharged_young_norm.png

x_old = df_dc[9:-1]['60-']
x_old_norm = (x_old.T / x_old.sum(axis=1)).T

print(x_old_norm)
# discharged         0         1
# date                          
# 2020-03-22  0.019608  0.980392
# 2020-03-29  0.060811  0.939189
# 2020-04-05  0.040590  0.959410
# 2020-04-12  0.035714  0.964286
# 2020-04-19  0.064394  0.935606
# 2020-04-26  0.126923  0.873077
# 2020-05-03  0.191667  0.808333
# 2020-05-10  0.173913  0.826087
# 2020-05-17  0.600000  0.400000
# 2020-05-24  0.238095  0.761905
# 2020-05-31  0.409091  0.590909
# 2020-06-07  0.461538  0.538462
# 2020-06-14  0.607143  0.392857
# 2020-06-21  0.347826  0.652174
# 2020-06-28  0.392157  0.607843
# 2020-07-05  0.676471  0.323529
# 2020-07-12  0.965812  0.034188
# 2020-07-19  1.000000  0.000000

x_old_norm.plot.bar(stacked=True)

bar_discharged_old_norm.png

Die Prozentsätze von jungen und älteren Menschen, deren entlassene Flaggen nicht auf "1" gesetzt sind, sind unten angegeben. Schließlich werden ältere Menschen in der Regel für einen längeren Zeitraum ins Krankenhaus eingeliefert.

pd.DataFrame({'20-39': x_young_norm[0], '60-': x_old_norm[0]}).plot.bar()

bar_discharged_young_old_norm.png

Verarbeitet von Matplotlib

Die Beispiele waren bisher mit dem plot () von DataFrame und der Funktion seaborn relativ einfach zu handhaben, müssen jedoch in einigen Fällen von Matplotlib behandelt werden.

Nehmen Sie als Beispiel den Übergang der Gesamtzahl der neuen Positiven.

Hier wird value_counts () verwendet, um die Datums- und Zeitspalten zu zählen und die Gesamtzahl der neuen Positiven für jedes Veröffentlichungsdatum zu berechnen. Beachten Sie, dass wenn Sie nicht nach sort_index () sortieren, diese in absteigender Reihenfolge angeordnet werden.

s_total = df['date'].value_counts().sort_index()

print(s_total)
# 2020-01-24      1
# 2020-01-25      1
# 2020-01-30      1
# 2020-02-13      1
# 2020-02-14      2
#              ... 
# 2020-07-27    131
# 2020-07-28    266
# 2020-07-29    250
# 2020-07-30    367
# 2020-07-31    463
# Name: date, Length: 164, dtype: int64

print(type(s_total))
# <class 'pandas.core.series.Series'>

print(type(s_total.index))
# <class 'pandas.core.indexes.datetimes.DatetimeIndex'>

Im Gegensatz zu den vorherigen Beispielen handelt es sich um "Serie" anstelle von "DataFrame", aber die Idee ist in beiden Fällen dieselbe.

Wenn ein Balkendiagramm mit "plot.bar ()" erstellt wird, überlappen sich die X-Achsen wie unten gezeigt.

s_total.plot.bar()

bar_total_ng.png

In dem Beispiel im Vergleich zur Vorwoche habe ich geschrieben, dass beim Generieren eines Liniendiagramms mit plot () Datum und Uhrzeit entsprechend formatiert werden, in diesem Fall jedoch nicht.

s_total.plot()

line_total_ng.png

Es scheint, dass der Grund, warum plot () nicht funktioniert, darin besteht, dass der Datums- und Zeitdatensatz im Index nicht periodisch ist (es tut mir leid, wenn es anders ist, weil ich es nicht im Detail untersucht habe).

Im Beispiel im Vergleich zur Vorwoche waren wöchentliche Daten ohne Auslassung vorhanden. In diesem Beispiel sind die Daten jedoch zu dem Zeitpunkt verfügbar, an dem die Anzahl der positiven Personen wie "2020-01-26" und "2020-01-27" "0" beträgt. Ist nicht vorhanden.

Fügen Sie mit "reindex ()" und "pd.date_range ()" Daten mit dem Wert "0" hinzu, auch an dem Datum und der Uhrzeit, an dem die Anzahl der Positiven "0" beträgt.

s_total_re = s_total.reindex(
    index=pd.date_range(s_total.index[0], s_total.index[-1]),
    fill_value=0
)

print(s_total_re)
# 2020-01-24      1
# 2020-01-25      1
# 2020-01-26      0
# 2020-01-27      0
# 2020-01-28      0
#              ... 
# 2020-07-27    131
# 2020-07-28    266
# 2020-07-29    250
# 2020-07-30    367
# 2020-07-31    463
# Freq: D, Name: date, Length: 190, dtype: int64

Dadurch werden Datum und Uhrzeit mit plot () entsprechend formatiert. Übrigens, wenn Sie die Protokollskalierung verwenden möchten, ist "logy = True".

s_total_re.plot()

line_total_ok.png

s_total_re.plot(logy=True)

line_total_ok_log.png

Auch in diesem Fall ist plot.bar () nutzlos.

s_total_re.plot.bar()

bar_total_ng_2.png

Für andere Typen als Liniendiagramme muss Matplotlib sie verarbeiten.

Stellen Sie Formatierer und Locator ein und generieren Sie ein Diagramm mit bar () von Matplotlib.

fig, ax = plt.subplots(figsize=(12, 4))

ax.xaxis.set_major_locator(mpl.dates.AutoDateLocator())
ax.xaxis.set_major_formatter(mpl.dates.DateFormatter('%Y-%m-%d'))

ax.xaxis.set_tick_params(rotation=90)

ax.bar(s_total.index, s_total)

bar_total_ok.png

Set_yscale ('log') wenn Sie eine Protokollskala wünschen.

fig, ax = plt.subplots(figsize=(12, 4))

ax.xaxis.set_major_locator(mpl.dates.AutoDateLocator())
ax.xaxis.set_major_formatter(mpl.dates.DateFormatter('%Y-%m-%d'))

ax.xaxis.set_tick_params(rotation=90)

ax.set_yscale('log')

ax.bar(s_total.index, s_total)

bar_total_ok_log.png

Wenn Sie eine Linie mit gleitendem Durchschnitt hinzufügen möchten, verwenden Sie "rollend ()".

print(s_total.rolling(7).mean())
# 2020-01-24           NaN
# 2020-01-25           NaN
# 2020-01-30           NaN
# 2020-02-13           NaN
# 2020-02-14           NaN
#                  ...    
# 2020-07-27    252.285714
# 2020-07-28    256.428571
# 2020-07-29    258.142857
# 2020-07-30    258.285714
# 2020-07-31    287.285714
# Name: date, Length: 164, dtype: float64

fig, ax = plt.subplots(figsize=(12, 4))

ax.xaxis.set_major_locator(mpl.dates.AutoDateLocator())
ax.xaxis.set_minor_locator(mpl.dates.DayLocator())
ax.xaxis.set_major_formatter(mpl.dates.DateFormatter('%Y-%m-%d'))

ax.xaxis.set_tick_params(labelsize=12)
ax.yaxis.set_tick_params(labelsize=12)

ax.grid(linestyle='--')
ax.margins(x=0)

ax.bar(s_total.index, s_total, width=1, color='#c0e0c0', edgecolor='black')
ax.plot(s_total.index, s_total.rolling(7).mean(), color='red')

bar_total_with_ma.png

Im obigen Beispiel wurden einige Einstellungen als Referenz hinzugefügt. margin (x = 0) ist das Abschneiden des linken und rechten Randes. Sie können die Farbe anhand des Namens oder des Farbcodes angeben.

schließlich

Die Daten, die für die Öffentlichkeit zugänglich sind, sind begrenzt, aber ich denke, dass Sie Ihr Verständnis vertiefen können, indem Sie selbst damit herumspielen. Bitte probieren Sie es aus.

Recommended Posts

Praxis der Datenanalyse durch Python und Pandas (Tokyo COVID-19 Data Edition)
Analyse von Finanzdaten durch Pandas und deren Visualisierung (2)
Datenanalyse mit Python-Pandas
Versuchen Sie, COVID-19 Tokyo-Daten mit Python zu kratzen
Erstellen Sie mit Python einen Entscheidungsbaum aus 0 und verstehen Sie ihn (3. Datenanalysebibliothek Pandas Edition)
Empfohlene Bücher und Quellen für die Datenanalyseprogrammierung (Python oder R)
Praktische Übung zur Datenanalyse mit Python ~ 2016 New Coder Survey Edition ~
Automatische Erfassung von Genexpressionsdaten durch Python und R.
Beispiel einer dreidimensionalen Skelettanalyse von Python
Pandas des Anfängers, vom Anfänger, für den Anfänger [Python]
Analyse des Röntgenmikrotomographiebildes durch Python
Datenanalyse Python
[CovsirPhy] COVID-19 Python-Paket für die Datenanalyse: Laden von Daten
[Python] Datenanalyse, maschinelles Lernen (Kaggle) -Datenvorverarbeitung-
Berechnung der technischen Indikatoren durch TA-Lib und Pandas
Emotionale Analyse umfangreicher Tweet-Daten durch NLTK
Aufgezeichnete Umgebung für die Datenanalyse mit Python
Grundlegende Bedienung von Python Pandas Series und Dataframe (1)
Python-Übungsdatenanalyse Zusammenfassung des Lernens, dass ich ungefähr 10 mit 100 Schlägen getroffen habe
[Python] Von der morphologischen Analyse von CSV-Daten bis zur CSV-Ausgabe und Diagrammanzeige [GiNZA]
[Python] Vergleich der Theorie und Implementierung der Hauptkomponentenanalyse durch Python (PCA, Kernel PCA, 2DPCA)
Praxis der Erstellung einer Datenanalyseplattform mit BigQuery und Cloud DataFlow (Datenverarbeitung)
Datenanalyse mit Python 2
Holen Sie sich mit Python eine große Menge von Starbas Twitter-Daten und probieren Sie die Datenanalyse Teil 1 aus
[Python] [Word] [python-docx] Einfache Analyse von Diff-Daten mit Python
Liste der Python-Bibliotheken für Datenwissenschaftler und Dateningenieure
Datenanalyse Übersicht Python
Aufbau einer Datenanalyseumgebung mit Python (IPython Notebook + Pandas)
Fordern Sie die Hauptkomponentenanalyse von Textdaten mit Python heraus
Zusammenfassung der beim Extrahieren von Daten verwendeten Pandas-Methoden [Python]
Geschichte der Bildanalyse von PDF-Dateien und Datenextraktion
Liste des Python-Codes, der bei der Big-Data-Analyse verwendet wird
[CovsirPhy] COVID-19 Python-Paket für die Datenanalyse: SIR-F-Modell
[CovsirPhy] COVID-19 Python-Paket für die Datenanalyse: S-R-Trendanalyse
Python-Datenanalysevorlage
[CovsirPhy] COVID-19 Python-Paket für die Datenanalyse: SIR-Modell
Analyse der Messdaten (2) -Hydrobacter und Anpassung, lmfit Empfehlung-
[CovsirPhy] COVID-19 Python-Paket für die Datenanalyse: Parameterschätzung
Visualisierung von Daten anhand einer erklärenden Variablen und einer objektiven Variablen
[Python-Anfängermemo] Bedeutung und Methode zur Bestätigung des fehlenden NaN-Werts vor der Datenanalyse
Datenanalyse mit Python
[CovsirPhy] COVID-19 Python-Paket für die Datenanalyse: Szenarioanalyse (Parametervergleich)
Führen Sie mit Python und Matplotlib eine Isostromanalyse offener Wasserkanäle durch
■ Kaggle-Übung für Anfänger - Einführung von Python - von Google Colaboratory
Anwendung von Python: Datenbereinigung Teil 3: Verwendung von OpenCV und Vorverarbeitung von Bilddaten
20200329_Einführung in die Datenanalyse mit Python 2nd Edition Personal Summary
Befreien Sie sich mit Python und regulären Ausdrücken von schmutzigen Daten
Datenanalyse basierend auf den Wahlergebnissen der Gouverneurswahl von Tokio (2020)
Scrapen der gewünschten Daten von der Website durch Verknüpfen von Python und Excel
[Einführung in Data Scientists] Grundlagen von Python ♬ Funktionen und Klassen
Zeichnen Sie Zeitreihendaten in Python mit Pandas und Matplotlib
Vergleich der Datenrahmenbehandlung in Python (Pandas), R, Pig
[Python] Zufällige Datenextraktion / -kombination aus DataFrame mit Random und Pandas
Mein Python-Datenanalyse-Container
Python 2-Serie und 3-Serie (Anaconda Edition)
Python für die Datenanalyse Kapitel 4
Statische Analyse von Python-Programmen
Visualisierung von Daten nach Präfektur
Lernnotizen zur Python-Datenanalyse
Python für die Datenanalyse Kapitel 2
Quellinstallation und Installation von Python