2015-10-08 19 views
5

Mam dwie ramki danych (df1 i df2), z których każda ma te same wiersze i kolumny. Chciałbym wziąć maksimum z tych dwóch ramek danych, element po elemencie. Ponadto, wynikiem dowolnego elementu o wartości maksymalnej z liczbą i NaN powinna być liczba. Podejście, które wdrożyłem do tej pory, wydaje się nieefektywne:Elementarne maksimum dwóch ramek danych Ignoring NaNs

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 

Jakieś inne pomysły? Dziękuję za Twój czas.

+0

Należy dodać co najmniej próbkę oryginalnego dataframe odtworzyć Twój problem. –

Odpowiedz

9

Można użyć where przetestować przeciwko innemu df df, gdzie stan jest True wartości od df są zwracane, gdy fałszywe są zwracane wartości z df1. Dodatkowo w przypadku, gdy NaN wartości są w df1 następnie dodatkowe wezwanie do fillna(df) użyje wartości z df wypełnić te NaN i powrócić żądaną DF:

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

Dzięki za sugestię! Niestety to nie odpowiada na pytanie. Jeśli niektóre elementy są NaN, wynik nie będzie wartością inną niż NaN. Na przykład rozważ df1.loc [0,0] = np.nan, a następnie df.where (df> df1, df1) będzie NaN dla elementu w miejscu [0,0] zamiast df. – DrTRD

+0

OK, myślę, że to zadziała 'df.where (df> df1, df1) .fillna (df)' – EdChum

Powiązane problemy