2013-06-12 32 views
19

我想用零替換pandas DataFrame列中的負值。爲pandas DataFrame列返回最大值零或值

是否有更簡潔的方式來構造這個表達式?

df['value'][df['value'] < 0] = 0 
+1

看起來你會怎樣在'numpy'中做這件事......我懷疑除了把它分解成兩條語句外,還有更簡潔的方法。 – mgilson

+0

也許類似'df ['value'] = max((df ['value'],0))' – John

回答

13

這裏是做它的規範的方法,雖然不一定更簡潔,更靈活(因爲你可以把這種任意列)

In [39]: df = DataFrame(randn(5,1),columns=['value']) 

In [40]: df 
Out[40]: 
     value 
0 0.092232 
1 -0.472784 
2 -1.857964 
3 -0.014385 
4 0.301531 

In [41]: df.loc[df['value']<0,'value'] = 0 

In [42]: df 
Out[42]: 
     value 
0 0.092232 
1 0.000000 
2 0.000000 
3 0.000000 
4 0.301531 
+0

更靈活(不太模糊)。 –

+0

這是Numpy代碼中常見的成語。 +1 – heltonbiker

+0

儘管在某些方面,np.clip或np.max解決方案更容易閱讀,但我認爲這是對我最初問題的最準確答案。 – bjornarneson

13

您可以使用clip method

import pandas as pd 
import numpy as np 
df = pd.DataFrame({'value': np.arange(-5,5)}) 
df['value'] = df['value'].clip(0, None) 
print(df) 

產生

value 
0  0 
1  0 
2  0 
3  0 
4  0 
5  0 
6  1 
7  2 
8  3 
9  4 
+2

在旁註中,你不需要'np .inf'作爲第二個參數。它默認爲None,在這種情況下是等價的。如果您擔心可讀性並留下第二個參數,則可以使用'df.value.clip_lower(0)'代替。 –

+0

@JoeKington:哦,謝謝! – unutbu

+0

對於它的價值,我認爲'pandas.DataFrame.clip'也表現得像'numpy'一樣。我只在5分鐘前意識到它沒有(並且你不需要第二個參數)! :) –

10

另一種可能性是使用numpy.maximum()。在我看來,這更直接。

import pandas as pd 
import numpy as np 
df['value'] = np.maximum(df['value'], 0) 

而且它也快2-3倍。

In [21]: df = pd.DataFrame({'value': np.arange(-1000000,1000000)}) 
In [22]: %timeit df.loc[df['value']<0,'value'] = 0 
10 loops, best of 3: 27.3 ms per loop 

In [23]: df = pd.DataFrame({'value': np.arange(-1000000,1000000)}) 
In [24]: %timeit df['value'] = np.maximum(df['value'], 0) 
100 loops, best of 3: 9.42 ms per loop 
+0

我認爲這很好,唯一不好的地方就是'np.max!= np.maximum',這使得這種糟糕的助記符 – maxymoo

0

讓我們只取大於零的值,留下那些與NaN一樣負的值(與非序列的幀一起工作),然後歸算。

df[df > 0].fillna(0)