98 votes

Concat et append de DataFrame Pandas

J'ai une liste de 4 dataframes pandas contenant une journée de données en ticks que je veux fusionner en un seul data frame. Je ne comprends pas le comportement de concat sur mes timestamps. Voir les détails ci-dessous :

data

[<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 35228 entries, 2013-03-28 00:00:07.089000+02:00 to 2013-03-28 18:59:20.357000+02:00
Data columns:
Price       4040  non-null values
Volume      4040  non-null values
BidQty      35228  non-null values
BidPrice    35228  non-null values
AskPrice    35228  non-null values
AskQty      35228  non-null values
dtypes: float64(6),
<class 'pandas.core.frame.DataFrame'>

DatetimeIndex: 33088 entries, 2013-04-01 00:03:17.047000+02:00 to 2013-04-01 18:59:58.175000+02:00
Data columns:
Price       3969  non-null values
Volume      3969  non-null values
BidQty      33088  non-null values
BidPrice    33088  non-null values
AskPrice    33088  non-null values
AskQty      33088  non-null values
dtypes: float64(6),
<class 'pandas.core.frame.DataFrame'>

DatetimeIndex: 50740 entries, 2013-04-02 00:03:27.470000+02:00 to 2013-04-02 18:59:58.172000+02:00
Data columns:
Price       7326  non-null values
Volume      7326  non-null values
BidQty      50740  non-null values
BidPrice    50740  non-null values
AskPrice    50740  non-null values
AskQty      50740  non-null values
dtypes: float64(6),
<class 'pandas.core.frame.DataFrame'>

DatetimeIndex: 60799 entries, 2013-04-03 00:03:06.994000+02:00 to 2013-04-03 18:59:58.180000+02:00
Data columns:
Price       8258  non-null values
Volume      8258  non-null values
BidQty      60799  non-null values
BidPrice    60799  non-null values
AskPrice    60799  non-null values
AskQty      60799  non-null values
dtypes: float64(6)]

Utilisation de append J'ai compris :

pd.DataFrame().append(data)

<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 179855 entries, 2013-03-28 00:00:07.089000+02:00 to 2013-04-03 18:59:58.180000+02:00
Data columns:
AskPrice    179855  non-null values
AskQty      179855  non-null values
BidPrice    179855  non-null values
BidQty      179855  non-null values
Price       23593  non-null values
Volume      23593  non-null values
dtypes: float64(6)

Utilisation de concat J'ai compris :

pd.concat(data)

<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 179855 entries, 2013-03-27 22:00:07.089000+02:00 to 2013-04-03 16:59:58.180000+02:00
Data columns:
Price       23593  non-null values
Volume      23593  non-null values
BidQty      179855  non-null values
BidPrice    179855  non-null values
AskPrice    179855  non-null values
AskQty      179855  non-null values
dtypes: float64(6)

Remarquez comment l'index change quand on utilise concat . Pourquoi est-ce que cela se produit et comment puis-je utiliser concat pour reproduire les résultats obtenus en utilisant append ? (Depuis concat semble tellement plus rapide ; 24,6 ms par boucle contre 3,02 s par boucle)

150voto

Mohsin Mahmood Points 655

Pandas concat vs append vs join vs merge

  • Concat offre la possibilité de joindre sur la base de l'axe (toutes les lignes ou toutes les colonnes).

  • Ajouter est le cas spécifique (axis=0, join='outer') de concat ( être déprécié utiliser concat)

  • Rejoignez est basé sur les index (définis par set_index) sur la façon dont la variable =['left', 'right', 'inner', 'couter']

  • Fusionner est basé sur une colonne particulière de chacun des deux cadres de données, ces colonnes sont des variables comme 'left_on', 'right_on', 'on'.

64voto

Jeff Points 27612

Donc ce que tu fais avec append et concat est presque équivalent. La différence est le DataFrame vide. Pour une raison quelconque, cela provoque un gros ralentissement, je ne sais pas exactement pourquoi, il faudra regarder à un moment donné. Vous trouverez ci-dessous une reconstitution de ce que vous avez fait.

J'utilise presque toujours concat (bien que dans ce cas, ils soient équivalents, sauf pour le cadre vide) ; si vous n'utilisez pas le cadre vide, ils auront la même vitesse.

In [17]: df1 = pd.DataFrame(dict(A = range(10000)),index=pd.date_range('20130101',periods=10000,freq='s'))

In [18]: df1
Out[18]: 
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 10000 entries, 2013-01-01 00:00:00 to 2013-01-01 02:46:39
Freq: S
Data columns (total 1 columns):
A    10000  non-null values
dtypes: int64(1)

In [19]: df4 = pd.DataFrame()

The concat

In [20]: %timeit pd.concat([df1,df2,df3])
1000 loops, best of 3: 270 us per loop

This is equavalent of your append

In [21]: %timeit pd.concat([df4,df1,df2,df3])
10 loops, best of 

 3: 56.8 ms per loop

52voto

Michael Dorner Points 730

J'ai implémenté un petit benchmark (veuillez trouver le fichier code sur Gist ) pour évaluer l'outil d'évaluation des pandas concat y append . J'ai mis à jour l'extrait de code et les résultats après le commentaire par ssk08 - Merci beaucoup !

Le benchmark a été réalisé sur un système Mac OS X 10.13 avec Python 3.6.2 et pandas 0.20.3.

+--------+---------------------------------+---------------------------------+
|        | ignore\_index=False              | ignore\_index=True               |
+--------+---------------------------------+---------------------------------+
| size   | append | concat | append/concat | append | concat | append/concat |
+--------+--------+--------+---------------+--------+--------+---------------+
| small  | 0.4635 | 0.4891 | 94.77 %       | 0.4056 | 0.3314 | 122.39 %      |
+--------+--------+--------+---------------+--------+--------+---------------+
| medium | 0.5532 | 0.6617 | 83.60 %       | 0.3605 | 0.3521 | 102.37 %      |
+--------+--------+--------+---------------+--------+--------+---------------+
| large  | 0.9558 | 0.9442 | 101.22 %      | 0.6670 | 0.6749 | 98.84 %       |
+--------+--------+--------+---------------+--------+--------+---------------+

Utilisation de ignore_index=False append est légèrement plus rapide, avec ignore_index=True concat est légèrement plus rapide.

en résumé Aucune différence significative entre concat y append .

13voto

nhanhoangle Points 119

Une autre chose à garder à l'esprit est que la méthode APPEND() de Pandas ne modifie pas l'objet original. Au contraire, elle en crée un nouveau avec les données combinées. En raison de l'implication de la création et du tampon de données, ses performances ne sont pas bonnes. Vous feriez mieux d'utiliser la fonction CONCAT() lorsque vous effectuez des opérations APPEND multiples.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X