2017-05-16 83 views
9

我有一個數據幀:熊貓元素方面的最小值最大值對沿一個軸系列

df = 
      A B C D 
DATA_DATE 
20170103 5.0 3.0 NaN NaN 
20170104 NaN NaN NaN 1.0 
20170105 1.0 NaN 2.0 3.0 

而且我有一系列

s = 
DATA_DATE 
20170103 4.0 
20170104 0.0 
20170105 2.2 

我想明智的元素max()運行功能並沿着df的列對齊s。換句話說,我想要得到

result = 
      A B C D 
DATA_DATE 
20170103 5.0 4.0 NaN NaN 
20170104 NaN NaN NaN 1.0 
20170105 2.2 NaN 2.2 3.0 

這樣做的最好方法是什麼?我已經選擇了single column comparisonseries to series comparison,但還沒有找到一種有效的方法來針對一個系列運行數據幀。

獎勵:不知道,如果答案是不言而喻的上面,但如何做到這一點,如果我要對齊沿sdf(假設的尺寸相符)?

回答

8

數據:

In [135]: df 
Out[135]: 
      A B C D 
DATA_DATE 
20170103 5.0 3.0 NaN NaN 
20170104 NaN NaN NaN 1.0 
20170105 1.0 NaN 2.0 3.0 

In [136]: s 
Out[136]: 
20170103 4.0 
20170104 0.0 
20170105 2.2 
Name: DATA_DATE, dtype: float64 

解決方案:

In [66]: df.clip_lower(s, axis=0) 
C:\Users\Max\Anaconda4\lib\site-packages\pandas\core\ops.py:1247: RuntimeWarning: invalid value encountered in greater_equal 
    result = op(x, y) 
Out[66]: 
      A B C D 
DATA_DATE 
20170103 5.0 4.0 NaN NaN 
20170104 NaN NaN NaN 1.0 
20170105 2.2 NaN 2.2 3.0 

,我們可以使用下面的技巧,以GED擺脫RuntimeWarning的:

In [134]: df.fillna(np.inf).clip_lower(s, axis=0).replace(np.inf, np.nan) 
Out[134]: 
      A B C D 
DATA_DATE 
20170103 5.0 4.0 NaN NaN 
20170104 NaN NaN NaN 1.0 
20170105 2.2 NaN 2.2 3.0 
+1

更清潔。 :) – ayhan

+0

@ayhan,謝謝! :-) – MaxU

+0

我試圖重現答案,但我得到了一堆Nan值。任何想法我可能做錯了什麼? – Moondra

6

這就是所謂的廣播和可以做如下:

import numpy as np 
np.maximum(df, s[:, None]) 
Out: 
      A B C D 
DATA_DATE      
20170103 5.0 4.0 NaN NaN 
20170104 NaN NaN NaN 1.0 
20170105 2.2 NaN 2.2 3.0 

這裏,s[:, None]將一個新的軸加入ss[:, np.newaxis]也可以達到同樣的效果。當你這樣做時,他們可以一起播出,因爲形狀(3, 4)(3, 1)有一個共同的元素。

ss[:, None]之間的區別:

s.values 
Out: array([ 4. , 0. , 2.2]) 

s[:, None] 
Out: 
array([[ 4. ], 
     [ 0. ], 
     [ 2.2]]) 

s.shape 
Out: (3,) 

s[:, None].shape 
Out: (3, 1) 

另一種方法是:

df.mask(df.le(s, axis=0), s, axis=0) 

Out: 
      A B C D 
DATA_DATE      
20170103 5.0 4.0 NaN NaN 
20170104 NaN NaN NaN 1.0 
20170105 2.2 NaN 2.2 3.0 

這寫着:比較DF和s。如果df較大,請使用df,否則使用s。

+1

不要賣自己短@ayhan,這是一個很好的答案。瞭解廣播並將系列與數據框進行比較。謝謝! – pshep123

+0

@ pshep123謝謝。 :) – ayhan

0

雖然可能有更好的解決方案對於你的問題,我相信這應該會給你你需要的東西:

for c in df.columns: 
    df[c] = pd.concat([df[c], s], axis=1).max(axis=1)