2012-03-20 48 views
20

Chcę wykonać operację łączenia/scalania/dołączania na ramce danych z indeksem czasu.dołączanie lub scalanie z nadpisywaniem w pandach

Załóżmy, że mam df1 i chcę dodać do niego df2. df2 może mieć mniej lub więcej kolumn i nakładających się indeksów. W przypadku wszystkich wierszy, w których indeksy są zgodne, jeśli df2 ma tę samą kolumnę co df1, chcę, aby wartości df1 zostały nadpisane wartościami z df2.

Jak mogę uzyskać żądany wynik?

Odpowiedz

22

Co powiecie na: df2.combine_first(df1)?

In [33]: df2 
Out[33]: 
        A   B   C   D 
2000-01-03 0.638998 1.277361 0.193649 0.345063 
2000-01-04 -0.816756 -1.711666 -1.155077 -0.678726 
2000-01-05 0.435507 -0.025162 -1.112890 0.324111 
2000-01-06 -0.210756 -1.027164 0.036664 0.884715 
2000-01-07 -0.821631 -0.700394 -0.706505 1.193341 
2000-01-10 1.015447 -0.909930 0.027548 0.258471 
2000-01-11 -0.497239 -0.979071 -0.461560 0.447598 

In [34]: df1 
Out[34]: 
        A   B   C 
2000-01-03 2.288863 0.188175 -0.040928 
2000-01-04 0.159107 -0.666861 -0.551628 
2000-01-05 -0.356838 -0.231036 -1.211446 
2000-01-06 -0.866475 1.113018 -0.001483 
2000-01-07 0.303269 0.021034 0.471715 
2000-01-10 1.149815 0.686696 -1.230991 
2000-01-11 -1.296118 -0.172950 -0.603887 
2000-01-12 -1.034574 -0.523238 0.626968 
2000-01-13 -0.193280 1.857499 -0.046383 
2000-01-14 -1.043492 -0.820525 0.868685 

In [35]: df2.comb 
df2.combine  df2.combineAdd  df2.combine_first df2.combineMult  

In [35]: df2.combine_first(df1) 
Out[35]: 
        A   B   C   D 
2000-01-03 0.638998 1.277361 0.193649 0.345063 
2000-01-04 -0.816756 -1.711666 -1.155077 -0.678726 
2000-01-05 0.435507 -0.025162 -1.112890 0.324111 
2000-01-06 -0.210756 -1.027164 0.036664 0.884715 
2000-01-07 -0.821631 -0.700394 -0.706505 1.193341 
2000-01-10 1.015447 -0.909930 0.027548 0.258471 
2000-01-11 -0.497239 -0.979071 -0.461560 0.447598 
2000-01-12 -1.034574 -0.523238 0.626968  NaN 
2000-01-13 -0.193280 1.857499 -0.046383  NaN 
2000-01-14 -1.043492 -0.820525 0.868685  NaN 

Zauważ, że przyjmuje wartości od df1 dla indeksów, które nie pokrywają się z df2. Jeśli to nie robi dokładnie tego, czego chcesz, byłbym skłonny poprawić tę funkcję/dodać do niej opcje.

+0

Myślę, że to jest rzeczywiście to, czego chcę, wielkie dzięki. – saroele

+0

Występuje problem z 'combine_first' - używanie go do łączenia trzech ramek danych o wielkości około 30 tysięcy wierszy przejmuje całą moją pamięć. Jakikolwiek sposób obejścia tego? – scry

+0

Myślę, że byłoby o wiele bardziej intuicyjne, gdyby ta funkcja była częścią funkcji 'df.update' z opcjonalnym argumentem' join = 'outer'' (obecnie tylko 'left' jest zaimplementowany). W moim przypadku 'df2' (obliczone z' df1') ma o wiele mniej kolumn niż 'df1' (ale niektóre, które nie są w' df1'), i chcę zaktualizować 'df1' z obliczonymi wartościami tam, gdzie to możliwe plus dodatkowe kolumny. W tym celu myślę, że 'df1.update (df2, join = 'outer')' byłoby o wiele łatwiejsze do zrozumienia niż 'df1 = df2.combine_first (df1)'. PS. Jest to drobna sprzeczka, ale poza tym 'panda' jest prawie wyłącznie niesamowita! =) – Axel

6

Do scalania w ten sposób przydatna jest metoda DataFrame update.

Biorąc przykłady z documentation:

import pandas as pd 
import numpy as np 

df1 = pd.DataFrame([[np.nan, 3., 5.], [-4.6, np.nan, np.nan], 
        [np.nan, 7., np.nan]]) 
df2 = pd.DataFrame([[-42.6, np.nan, -8.2], [-5., 1.6, 4]], 
        index=[1, 2]) 

danych przed update: Aktualizacja

>>> df1 
    0 1 2 
0 NaN 3.0 5.0 
1 -4.6 NaN NaN 
2 NaN 7.0 NaN 
>>> 
>>> df2 
     0 1 2 
1 -42.6 NaN -8.2 
2 -5.0 1.6 4.0 

Powiedzmy df1 z danymi z df2:

df1.update(df2) 

danych po aktualizacji:

>>> df1 
     0 1 2 
0 NaN 3.0 5.0 
1 -42.6 NaN -8.2 
2 -5.0 1.6 4.0 

Uwagi:

  • Ważne jest, aby zauważyć, że jest to działanie "na miejscu", modyfikując DataFrame który wywołuje update.
+3

To jest bardziej intuicyjne niż 'combine_first', ponieważ działa dokładnie tak jak metoda' update', którą znamy z dyktowania. – saroele