J'ai entendu dire que les courts discours et les jupes sont meilleurs.
Même dans l'analyse des données, je veux faire autant d'expériences que possible, donc Les travaux répétitifs de routine tels que le prétraitement doivent être aussi courts que possible.
Je pense que le profilage est utile dans de tels cas.
Récemment, j'ai décidé de traiter des données de plusieurs dizaines de Go ~ en privé.
À travers ce travail, sur le traitement parallèle, le profilage, etc. J'ai fait une petite découverte, alors j'aimerais pouvoir la partager.
Le premier est la découverte lors du profilage avec line_profiler
.
Beaucoup de gens ont écrit sur line_profiler, donc s'il vous plaît vérifier. C'est un super projet.
Je ne peux pas vous montrer les données qui ont été réellement utilisées. .. .. Nous allons procéder avec des exemples de données, qui ont une structure similaire à ces données.
In [1]: df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 100000 entries, 0 to 99999
Data columns (total 3 columns):
key 100000 non-null int64
data1 100000 non-null int64
data2 100000 non-null int64
dtypes: int64(3)
memory usage: 3.1 MB
In [2]: df.head()
Out[2]:
key data1 data2
0 1800 4153 159
1 5568 6852 45
2 432 7598 418
3 4254 9412 931
4 3634 8204 872
Le nombre réel de données est de dizaines de millions de lignes, Puisqu'il s'agit ici d'exemples de données, il est réduit à 100 000 lignes.
Le code suivant a été agrégé (il est redondant en raison du profilage ligne par ligne).
def proc1():
chunker = pd.read_csv('./data/testdata.csv', chunksize=10000)
li = []
for df in chunker:
#Changer le nom de la colonne
df.rename(columns={'data': 'value1', 'data2': 'value2'}, inplace=True)
#Agréger pour chaque clé et prendre le total de value1
li.append(df.groupby('key')['value1'].sum())
g = pd.concat(li, axis=1)
return g.sum(axis=1)
line_profiler
Cette fois, il est utilisé dans le notebook ipython.
%load_ext line_profiler
Vous pouvez y accéder avec la commande magique % lprun
.
Utilisons ceci pour mesurer le proc1
ci-dessus.
In [3]: %load_ext line_profiler
In [4]: %lprun -f proc1 proc1()
Timer unit: 1e-06 s
Total time: 0.060401 s
File: <ipython-input-105-0457ade3b36e>
Function: proc1 at line 1
Line # Hits Time Per Hit % Time Line Contents
==============================================================
1 def proc1():
2 1 1785 1785.0 3.0 chunker = pd.read_csv('./data/coltest.csv', chunksize=100000)
3
4 1 2 2.0 0.0 li = []
5 2 49155 24577.5 81.4 for df in chunker:
6 1 1932 1932.0 3.2 df.rename(columns={'data': 'value1', 'data2': 'value2'}, inplace=True)
7 1 4303 4303.0 7.1 li.append(df.groupby('key')['value1'].sum())
8
9 1 2723 2723.0 4.5 g = pd.concat(li, axis=1)
10 1 501 501.0 0.8 return g.sum(axis=1)
Jusqu'à ce que j'exécute line_profiler
, c'était comme" Je me demande si le chargement dans le partage de fichiers est lent ". C'est lent, mais il y a d'autres parties qui prennent beaucoup de temps.
a. La partie de «df.rename ...» prend environ la moitié du processus d'agrégation de «groupby» en termes de% de temps (pourcentage de l'ensemble).
read_csv
.
――Il semble y avoir une opinion selon laquelle vous n'avez pas à le changer en premier lieu.b. Si vous n'utilisez pas la colonne «valeur2», vous ne devez pas non plus la lire en utilisant l'option «utilitaires» de «read_csv».
Je pensais que cela prendrait plus de temps que prévu pour traiter «renommer». Je pense que le "line_profiler" qui a fait une telle découverte est très bon.
Ensuite, je voudrais écrire un mémo de travail sur le traitement parallèle d'ipython.
Recommended Posts