2015-10-08 20 views
5

Ho due dataframes (df1 e df2) che hanno le stesse righe e colonne. Vorrei prendere il massimo di questi due dataframes, elemento per elemento. Inoltre, il risultato di ogni numero massimo di elementi con un numero e NaN dovrebbe essere il numero. L'approccio che ho implementato finora sembra inefficiente:Numero massimo di due DataFrames Ignorare NaN

def element_max(df1,df2): 
    import pandas as pd 
    cond = df1 >= df2 
    res = pd.DataFrame(index=df1.index, columns=df1.columns) 
    res[(df1==df1)&(df2==df2)&(cond)] = df1[(df1==df1)&(df2==df2)&(cond)] 
    res[(df1==df1)&(df2==df2)&(~cond)] = df2[(df1==df1)&(df2==df2)&(~cond)] 
    res[(df1==df1)&(df2!=df2)&(~cond)] = df1[(df1==df1)&(df2!=df2)] 
    res[(df1!=df1)&(df2==df2)&(~cond)] = df2[(df1!=df1)&(df2==df2)] 
    return res 

Altre idee? Grazie per il tuo tempo.

+0

Aggiungi almeno un campione del dataframe originale di riprodursi il tuo problema. –

risposta

9

È possibile utilizzare where per testare la vostra df df contro un altro, in cui la condizione è True, i valori da df vengono restituiti, quando falso vengono restituiti i valori da df1. Inoltre, nel caso in cui NaN valori sono in df1 poi un ulteriore invito a fillna(df) utilizzerà i valori da df per riempire quelle NaN e restituire il df desiderata:

In [178]: 
df = pd.DataFrame(np.random.randn(5,3)) 
df.iloc[1,2] = np.NaN 
print(df) 
df1 = pd.DataFrame(np.random.randn(5,3)) 
df1.iloc[0,0] = np.NaN 
print(df1) 

      0   1   2 
0 2.671118 1.412880 1.666041 
1 -0.281660 1.187589  NaN 
2 -0.067425 0.850808 1.461418 
3 -0.447670 0.307405 1.038676 
4 -0.130232 -0.171420 1.192321 
      0   1   2 
0  NaN -0.244273 -1.963712 
1 -0.043011 -1.588891 0.784695 
2 1.094911 0.894044 -0.320710 
3 -1.537153 0.558547 -0.317115 
4 -1.713988 -0.736463 -1.030797 

In [179]: 
df.where(df > df1, df1).fillna(df) 

Out[179]: 
      0   1   2 
0 2.671118 1.412880 1.666041 
1 -0.043011 1.187589 0.784695 
2 1.094911 0.894044 1.461418 
3 -0.447670 0.558547 1.038676 
4 -0.130232 -0.171420 1.192321 
+0

Grazie per il suggerimento! Sfortunatamente questo non risponde alla domanda. Se alcuni degli elementi sono NaN, il risultato non sarà il valore non NaN. Ad esempio, si consideri df1.loc [0,0] = np.nan quindi df.where (df> df1, df1) sarà NaN per l'elemento nella posizione [0,0] anziché df. – DrTRD

+0

OK, penso che funzionerà 'df.where (df> df1, df1) .fillna (df)' – EdChum