Lors du traitement d'une grande quantité de données à l'aide de pandas Il faut souvent des dizaines de minutes à quelques heures pour traiter quelques Go, et des jours si vous n'êtes pas doué. Si le traitement est lent, le travail à effectuer ne se poursuivra pas Notez comment vous pouvez accélérer avec une simple modification du code source
index | name | weight | height |
---|---|---|---|
0 | Tanaka | 160.1 | 60.1 |
1 | Suzuki | 172.4 | 75.0 |
2 | Saitou | 155.8 | 42.2 |
... | |||
999998 | Morita | 167.9 | 94.07 |
999999 | Satou | 177.7 | 80.3 |
Par exemple, si vous avez un bloc de données comme celui ci-dessus Lors du calcul de la valeur moyenne du poids et de la taille, il semble que le processus soit décrit comme suit.
Mauvais modèle
import pandas as pd
sr_means = df.mean()
mean_height = sr_means['height']
mean_weight = sr_means['weight']
Cependant, en raison du nom de colonne contenant la chaîne, le code ci-dessus prend beaucoup de temps à calculer
En modifiant la description comme indiqué ci-dessous, le traitement sera d'un ordre de grandeur plus rapide.
Bon modèle
import pandas as pd
sr_means = df[['height', 'weight']].mean()
mean_height = sr_means['height']
mean_weight = sr_means['weight']
Post-scriptum: bon modèle
import pandas as pd
sr_means = df.mean(numeric_only = True)
mean_height = sr_means['height']
mean_weight = sr_means['weight']
Mesurez en fait le temps
Mesure réelle
import pandas as pd
import numpy as np
N = 100000
df_test = pd.DataFrame(
{
'name':['abc'] * N,
'weight': np.random.normal(60, 5, N),
'height': np.random.normal(160, 5, N)
}
)
print("df_test.mean()")
%time df_test.mean()
print("df_test[['height', 'weight']].mean()")
%time df_test[['height', 'weight']].mean()
Les résultats ci-dessus sont ci-dessous. Ce dernier est d'environ quatre ordres de grandeur plus rapide, même en considérant que le nombre de colonnes à calculer est réduit de un.
résultat
df_test.mean()
Wall time: 3.06 s
df_test[['height', 'weight']].mean()
Wall time: 4 ms
Par exemple, si vous souhaitez arrondir le poids de la colonne à un entier, vous pouvez utiliser la fonction round. Si vous n'êtes pas familier avec python et comment écrire de nos jours, vous avez tendance à écrire en utilisant l'instruction for. Utilisons la carte des fonctions d'ordre supérieur. (Je vais omettre ce qu'est la fonction d'ordre supérieur dans cet article)
Mauvais modèle
#Appliquer la fonction arrondie à l'élément
for idx in range(len(df_test['weight'].index)):
df_test['weight'][idx] = round(df_test['weight'][idx])
Réécrire ci-dessous en utilisant la carte
Bon modèle
#Appliquer la fonction arrondie à l'élément
df_test['weight'] = df_test['weight'].map(round)
Je vais également mesurer le temps cette fois. Étant donné que l'instruction for est trop lente, réduisez le nombre de données
Mesure réelle
def func(sr):
for idx in range(len(sr.index)):
sr[idx] = round(sr[idx])
return(sr)
N = 1000
df_test = pd.DataFrame(
{
'name':['abc'] * N,
'weight': np.random.normal(60, 5, N),
'height': np.random.normal(160, 5, N)
}
)
print("Pour pour")
%time df_test['weight'] = func(df_test['weight'])
print("Pour la carte")
%time df_test['weight'] = df_test['weight'].map(round)
Le résultat est ci-dessous. Ce qu'une carte peut traiter à la vitesse de la lumière devient ridiculement lent avec une déclaration for Parce qu'il ne s'agit que de 100 éléments de données C'est effrayant quand on pense à gérer 1 à 100 millions de données
résultat
Pour pour
Wall time: 22.1 s
Pour la carte
Wall time: 0 ns
Simplement en améliorant les deux processus ci-dessus Auparavant, le traitement des données prenait une journée, mais elles peuvent désormais être traitées en quelques minutes. Je veux l'améliorer régulièrement.