2012-06-19 28 views
29

Tengo dos dataframes, ambos indexados por timeseries. Necesito agregar los elementos para formar un nuevo dataframe, pero solo si el índice y la columna son los mismos. Si el artículo no existe en uno de los dataframe s, se debe tratar como cero.Agregar dos marcos de datos de pandas

He intentado usar .add, pero esta suma independientemente del índice y la columna. También probé un simple combined_data = dataframe1 + dataframe2 pero esto da un NaN si ambos dataframes no tienen el elemento.

¿Alguna sugerencia?

+0

Puede aclarar lo que desea que suceda si un elemento no existe en una o ambas tramas de datos? Usted dice que si el elemento no existe en * un * marco de datos, debe tratarse como cero --- ¿quiere decir que el valor en ese marco de datos debe tratarse como cero y agregarse al valor del otro marco de datos, o quiere decir el valor en el marco de datos del resultado debe ser cero? Además, dices 'df1 + df2' no funciona porque da NaN si ambos no tienen el elemento. ¿Qué quieres que pase en este caso? ¿Quieres un cero en el resultado? – BrenBarn

Respuesta

48

¿Qué tal x.add(y, fill_value=0)?

import pandas as pd 

df1 = pd.DataFrame([(1,2),(3,4),(5,6)], columns=['a','b']) 
Out: 
    a b 
0 1 2 
1 3 4 
2 5 6 

df2 = pd.DataFrame([(100,200),(300,400),(500,600)], columns=['a','b']) 
Out: 
    a b 
0 100 200 
1 300 400 
2 500 600 

df_add = df1.add(df2, fill_value=0) 
Out: 
    a b 
0 101 202 
1 303 404 
2 505 606 
+0

Perfecto, justo lo que buscaba. Gracias – cs0679

7

Si he entendido bien, usted quiere algo como:

(x.reindex_like(y).fillna(0) + y.fillna(0)).fillna(0) 

Esto le dará a la suma de las dos tramas de datos. Si un valor está en un marco de datos y no en el otro, el resultado en esa posición será ese valor existente. Si falta un valor en ambos dataframes, el resultado en esa posición será cero.

>>> x 
    A B C 
0 1 2 NaN 
1 3 NaN 4 
>>> y 
    A B C 
0 8 NaN 88 
1 2 NaN 5 
2 10 11 12 
>>> (x.reindex_like(y).fillna(0) + y.fillna(0)).fillna(0) 
    A B C 
0 9 2 88 
1 5 0 9 
2 10 11 12 
+1

Gracias, pero no expliqué muy bien mis datos ya que tengo columnas diferentes en ambos DataFrames, p. Ej. A, B, C en el dataframe1 y A, B, D en el dataframe 2. El resultado debe ser un dataframe con A, B, C, D – cs0679

+0

Esta respuesta funciona para mí use-case. ¡Gracias! – ivrin

0

Para hacer más general la respuesta ... primero voy a tomar el índice común para sincronizar ambas tramas de datos, entonces se unirá a cada uno de ellos a mi patrón (fechas) y voy a resumir las columnas de el mismo nombre y, finalmente, se unen las dos tramas de datos (borrar columnas añadidas en uno de ellos),

se puede ver un ejemplo (con precios de las acciones de Google tomadas de Google) aquí:

import numpy as np 
import pandas as pd 
import datetime as dt 

prices = pd.DataFrame([[553.0, 555.5, 549.3, 554.11, 0], 
         [556.8, 556.8, 544.05, 545.92, 545.92], 
         [545.5, 546.89, 540.97, 542.04, 542.04]], 
         index=[dt.datetime(2014,11,04), dt.datetime(2014,11,05), dt.datetime(2014,11,06)], 
         columns=['Open', 'High', 'Low', 'Close', 'Adj Close']) 

corrections = pd.DataFrame([[0, 555.22], [1238900, 0]], 
        index=[dt.datetime(2014,11,3), dt.datetime(2014,11,4)], 
        columns=['Volume', 'Adj Close']) 

dates = pd.DataFrame(prices.index, columns = ['Dates']).append(pd.DataFrame(corrections.index, columns = ['Dates'])).drop_duplicates('Dates').set_index('Dates').sort(axis=0) 
df_corrections = dates.join(corrections).fillna(0) 
df_prices = dates.join(prices).fillna(0) 

for col in prices.columns: 
    if col in corrections.columns: 
     df_prices[col]+=df_corrections[col] 
     del df_corrections[col] 

df_prices = df_prices.join(df_corrections) 
1

tanto las respuestas anteriores - fillna(0) y una adición directa le daría valores Nan si cualquiera de ellos tiene estructuras diferentes.

que es mejor usar fill_value

df.add(other_df, fill_value=0)

Cuestiones relacionadas