MultiIndex est utile pour extraire des lignes à l'aide de plusieurs clés, mais je recherchais plusieurs clés sans connaître son existence, alors comparons la vitesse d'exécution avec et sans MultiIndex. J'ai fait.
L'exécution du code et la mesure de la vitesse ont été effectuées sur le Jupyter Notebook. Aussi, le code ci-dessous
import pandas as pd
Est en cours d'exécution.
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
Essayez d'importer sample.csv dans DataFrame.
df1 = pd.read_csv("sample.csv")
Ensuite, il sera lu comme ceci.
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]
Résultat de l’exécution </ 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]
Résultat de l’exécution </ b>
1.44 ms ± 101 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
La méthode 1 nécessitait un temps d'exécution considérable lors du traitement d'une grande quantité de données, la méthode 2 a donc été utilisée pour le traitement.
Créez un élément unique en ajoutant les trois éléments de la ville, de l'année et du nombre sous forme de chaîne de caractères.
df2 = pd.read_csv("sample.csv")
# city, year,Extraire la colonne numérique sous forme de liste (les éléments sont convertis en str)
cities = list(map(str, df2["city"].values.tolist()))
years = list(map(str, df2["year"].values.tolist()))
numbers = list(map(str, df2["number"].values.tolist()))
#Ajoutez trois chaînes ensemble pour générer une clé unique
keys = [city+year+number for city, year, number in zip(cities, years, numbers)]
df2["key"] = keys
Ensuite, un tel DataFrame est créé.
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]
Résultat de l’exécution </ b> 2.5 ms ± 136 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit df2[df2["key"] == "2019Tokyo1"].iloc[0]
Résultat de l’exécution </ b> 569 µs ± 5.39 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Vous pouvez voir que la vitesse d'exécution, y compris la lecture csv, ne change pas, mais la vitesse d'exécution de la recherche n'a augmenté que de l'ordre de la microseconde.
Maintenant que j'ai appris cette méthode pour la première fois, examinons laquelle est plus rapide que la méthode 2. Consultez la documentation officielle (https://pandas.pydata.org/pandas-docs/stable/user_guide/advanced.html) pour plus d'informations sur MultiIndex.
Si vous spécifiez la ville, l'année et le nombre comme index, ils seront lus comme suit.
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)]
Résultat de l’exécution </ b> 2.64 ms ± 148 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit df2[df2["key"] == "2019Tokyo1"].iloc[0]
Résultat de l’exécution </ b> 151 µs ± 12.1 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Bien qu'il n'y ait pas de grande différence dans la vitesse d'exécution, y compris la lecture csv, le résultat est que la vitesse d'exécution lors de la lecture à l'avance est environ 3,8 fois plus rapide que la méthode 2.
Les résultats obtenus à ce jour sont résumés dans le tableau ci-dessous.
th> | Méthode 1 th> | Méthode 2 th> | Méthode 3 th> tr> thead> |
---|---|---|---|
Y compris la lecture csv th> | 2,65 ms td> | 2,5 ms td> | 2,64 ms td> tr> |
Recherche uniquement th> | 1,44 ms td> | 569 µs td> | 151 µs td> tr> tbody> table>
La méthode 2 que j'utilisais était un peu plus rapide en termes de temps d'exécution, y compris la lecture csv, mais une fois lue, il était plus rapide d'utiliser MultiIndex.
À propos, la méthode 2 rend le code plus long et les données à stocker dans le DataFrame augmentent, il semble donc préférable d'utiliser MultiIndex.
référenceÀ propos de MultiIndex of pandas Mesurer la vitesse du code avec jupyter Recommended Posts |