2016-12-29 30 views
3

我想在Pandas中將另一個數據框除以另一個數據框,以最終表示百分比變化。這兩個數據幀值都包含NaN和0.現在,當我將一個數據幀除以另一個數據幀時,兩個數據幀的值爲零的結果是NaN。我知道爲什麼0/0被設爲np.nan,但是從百分比變化的角度來看,我需要0/0爲0如何在Python熊貓中使零歸零?

什麼是完成這一任務的乾淨的方式?

重現問題:

import pandas as pd 
import numpy as np 

data_with_zeros = pd.DataFrame({'a': [2, np.nan, 0, 3], 'b': [np.nan, 2, 0, 6]}) 

data_with_zeros['a'].div(data_with_zeros['b'], fill_value=0) 

結果:

0   inf 
1   0.0 
2   NaN 
3   0.5 
dtype: float64 
+0

不會增加一個'fillna(0)'在最終會給你想要的結果,因爲'a'中的所有非零值會在'b'遇到零值時變成+/-'np.inf'? –

+0

不,這會導致缺少a和b值的值也設置爲0。這些值應該保持爲NaN。 – Niels

回答

2

這裏與dataframe.where method的方法 -

mask = (data_with_zeros[['a','b']].values == [0,0]).all(1) 
data_with_zeros['a'].div(data_with_zeros['b'], fill_value=0).where(~mask,0) 

或者mask可以在一個位來創建更直觀的方式,像這樣 -

mask = (data_with_zeros.a == 0) & (data_with_zeros.b == 0) 

樣品試驗 -

案例#1:

In [66]: data_with_zeros 
Out[66]: 
    a b 
0 2.0 NaN 
1 NaN 2.0 
2 0.0 0.0 
3 3.0 6.0 

In [67]: mask = (data_with_zeros.a == 0) & (data_with_zeros.b == 0) 

In [68]: data_with_zeros['a'].div(data_with_zeros['b'], fill_value=0).where(~mask,0) 
Out[68]: 
0   inf 
1 0.000000 
2 0.000000 
3 0.500000 
dtype: float64 

案例#2:

In [70]: data_with_zeros 
Out[70]: 
    a b 
0 2.0 0.0 
1 NaN 2.0 
2 0.0 0.0 
3 3.0 6.0 

In [71]: mask = (data_with_zeros.a == 0) & (data_with_zeros.b == 0) 

In [72]: data_with_zeros['a'].div(data_with_zeros['b'], fill_value=0).where(~mask,0) 
Out[72]: 
0   inf 
1 0.000000 
2 0.000000 
3 0.500000 
dtype: float64 
1

更換inf

In [61]: data_with_zeros['a'].div(data_with_zeros['b'], fill_value=0).replace({np.inf: 0}) 
Out[61]: 
0 0.0 
1 0.0 
2 NaN 
3 0.5 
dtype: float64 
+0

這不是一個問題的答案。我需要0/0爲0. x/0允許爲inf – Niels

1

除了由Divakar提供的解決方案,該函數使用方法做一個數據幀/數據幀劃分:

def divide(a, other, fill_value=None): 

    serie_name = a.name 
    mask = ((a == 0) & (other[serie_name] == 0)) 
    result_with_zeros = a.div(other[serie_name], fill_value=fill_value) 
    result_filled = result_with_zeros.where(~mask,0) 

    return result_filled 

data_with_zeros.apply(divide, args=(data_with_zeros,)) 

結果:

a b 
0 1.0 0.0 
1 NaN 1.0 
2 0.0 0.0 
3 1.0 1.0