MultiIndex ist nützlich, um Zeilen mit mehreren Schlüsseln zu extrahieren, aber ich habe nach mehreren Schlüsseln gesucht, ohne deren Existenz zu kennen. Vergleichen wir also die Ausführungsgeschwindigkeit mit und ohne MultiIndex. Ich tat.
Die Codeausführung und Geschwindigkeitsmessung wurden auf dem Jupyter Notebook durchgeführt. Auch der Code unten
import pandas as pd
Läuft.
sample.csv
city,year,number,dividion
Tokyo,2019,1,A
Tokyo,2019,2,B
Tokyo,2020,1,C
Tokyo,2020,2,D
Tokyo,2018,1,E
Tokyo,2018,2,F
Kyoto,2019,1,G
Kyoto,2019,2,H
Kyoto,2020,1,I
Kyoto,2020,2,J
Kyoto,2018,1,K
Kyoto,2018,2,L
Versuchen Sie, sample.csv in DataFrame zu importieren.
df1 = pd.read_csv("sample.csv")
Dann wird es so gelesen.
city | year | number | dividion | |
---|---|---|---|---|
0 | Tokyo | 2019 | 1 | A |
1 | Tokyo | 2019 | 2 | B |
2 | Tokyo | 2020 | 1 | C |
3 | Tokyo | 2020 | 2 | D |
4 | Tokyo | 2018 | 1 | E |
5 | Tokyo | 2018 | 2 | F |
6 | Kyoto | 2019 | 1 | G |
7 | Kyoto | 2019 | 2 | H |
8 | Kyoto | 2020 | 1 | I |
9 | Kyoto | 2020 | 2 | J |
10 | Kyoto | 2018 | 1 | K |
11 | Kyoto | 2018 | 2 | L |
%%timeit
df1 = pd.read_csv("sample.csv")
df1[(df1["city"] == "Tokyo")&(df1["year"] == 2019)&(df1["number"] == 1)].iloc[0]
Ausführungsergebnis </ b> 2.65 ms ± 48.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit df1[(df1["city"] == "Tokyo")&(df1["year"] == 2019)&(df1["number"] == 1)].iloc[0]
Ausführungsergebnis </ b>
1.44 ms ± 101 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Methode 1 erforderte eine beträchtliche Ausführungszeit bei der Verarbeitung einer großen Datenmenge, weshalb Methode 2 für die Verarbeitung verwendet wurde.
Erstellen Sie ein eindeutiges Element, indem Sie die drei Elemente Stadt, Jahr und Zahl als Zeichenfolge hinzufügen.
df2 = pd.read_csv("sample.csv")
# city, year,Extrahieren Sie die Zahlenspalte als Liste (Elemente werden in str konvertiert)
cities = list(map(str, df2["city"].values.tolist()))
years = list(map(str, df2["year"].values.tolist()))
numbers = list(map(str, df2["number"].values.tolist()))
#Fügen Sie drei Zeichenfolgen hinzu, um einen eindeutigen Schlüssel zu generieren
keys = [city+year+number for city, year, number in zip(cities, years, numbers)]
df2["key"] = keys
Dann wird ein solcher DataFrame erstellt.
city | year | number | dividion | key | |
---|---|---|---|---|---|
0 | Tokyo | 2019 | 1 | A | Tokyo20191 |
1 | Tokyo | 2019 | 2 | B | Tokyo20192 |
2 | Tokyo | 2020 | 1 | C | Tokyo20201 |
3 | Tokyo | 2020 | 2 | D | Tokyo20202 |
4 | Tokyo | 2018 | 1 | E | Tokyo20181 |
5 | Tokyo | 2018 | 2 | F | Tokyo20182 |
6 | Kyoto | 2019 | 1 | G | Kyoto20191 |
7 | Kyoto | 2019 | 2 | H | Kyoto20192 |
8 | Kyoto | 2020 | 1 | I | Kyoto20201 |
9 | Kyoto | 2020 | 2 | J | Kyoto20202 |
10 | Kyoto | 2018 | 1 | K | Kyoto20181 |
11 | Kyoto | 2018 | 2 | L | Kyoto20182 |
df2 = pd.read_csv("sample.csv")
cities = list(map(str, df2["city"].values.tolist()))
years = list(map(str, df2["year"].values.tolist()))
numbers = list(map(str, df2["number"].values.tolist()))
keys = [city+year+number for city, year, number in zip(cities, years, numbers)]
df2["key"] = keys
df2[df2["key"] == "Tokyo20191"].iloc[0]
Ausführungsergebnis </ b> 2.5 ms ± 136 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit df2[df2["key"] == "2019Tokyo1"].iloc[0]
Ausführungsergebnis </ b> 569 µs ± 5.39 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Sie können sehen, dass sich die Ausführungsgeschwindigkeit einschließlich des CSV-Lesens nicht ändert, aber die Ausführungsgeschwindigkeit der Suche hat sich nur auf die Größenordnung von Mikrosekunden erhöht.
Nachdem ich diese Methode zum ersten Mal gelernt habe, wollen wir untersuchen, welche Methode schneller als Methode 2 ist. Weitere Informationen zu MultiIndex finden Sie in der offiziellen Dokumentation (https://pandas.pydata.org/pandas-docs/stable/user_guide/advanced.html).
Wenn Sie Stadt, Jahr und Nummer als Indizes angeben, wird dies wie folgt gelesen.
df3 = pd.read_csv("sample.csv",index_col=["city","year","number"])
dividion | |||
---|---|---|---|
city | year | number | |
Tokyo | 2019 | 1 | A |
2 | B | ||
2020 | 1 | C | |
2 | D | ||
2018 | 1 | E | |
2 | F | ||
Kyoto | 2019 | 1 | G |
2 | H | ||
2020 | 1 | I | |
2 | J | ||
2018 | 1 | K | |
2 | L |
df3 = pd.read_csv("sample.csv",index_col=["city","year","number"])
df3.loc[("Tokyo",2019,1)]
Ausführungsergebnis </ b> 2.64 ms ± 148 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit df2[df2["key"] == "2019Tokyo1"].iloc[0]
Ausführungsergebnis </ b> 151 µs ± 12.1 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Obwohl es keinen großen Unterschied in der Ausführungsgeschwindigkeit einschließlich des CSV-Lesens gibt, ist das Ergebnis, dass die Ausführungsgeschwindigkeit beim Lesen im Voraus etwa 3,8-mal schneller ist als bei Methode 2.
Die bisherigen Ergebnisse sind in der folgenden Tabelle zusammengefasst.
th> | Methode 1 th> | Methode 2 th> | Methode 3 th> tr> thead> |
---|---|---|---|
Einschließlich CSV-Lesung th> | 2,65 ms td> | 2,5 ms td> | 2,64 ms td> tr> |
Nur suchen th> | 1,44 ms td> | 569 µs td> | 151 µs td> tr> tbody> table>
Die von mir verwendete Methode 2 war in Bezug auf die Ausführungszeit einschließlich des CSV-Lesens etwas schneller, aber nach dem Lesen war die Verwendung von MultiIndex schneller.
Übrigens verlängert Methode 2 den Code und die im DataFrame zu speichernden Daten nehmen zu. Grundsätzlich scheint es also besser zu sein, MultiIndex zu verwenden.
ReferenzÜber MultiIndex von Pandas Codegeschwindigkeit mit Jupiter messen Recommended Posts |