2013-06-12 11 views
19

Chcę zamienić ujemne wartości w kolumnie DataFrame pandas na zero.Powrót maksimum zera lub wartość dla pandy DataFrame kolumna

Czy istnieje bardziej zwięzły sposób na skonstruowanie tego wyrażenia?

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

Wygląda to tak, jakbyś zrobił to w "numpy" ... Wątpię, żeby był bardziej zwięzły, niż rozbicie go na 2 zdania. – mgilson

+0

Może coś takiego jak 'df ['value'] = max ((df ['value'], 0))' – John

Odpowiedz

13

Oto kanoniczny sposób to zrobić, ale niekoniecznie bardziej zwięzłe, jest bardziej elastyczny (w które można zastosować to do dowolnych kolumn)

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

O wiele bardziej elastyczny (i mniej niejasny). –

+0

To jest typowy idiom w kodzie Numpy. +1 – heltonbiker

+0

Chociaż pod pewnymi względami rozwiązania np.clip lub np.max są łatwiejsze do odczytania, uważam, że jest to najbardziej precyzyjna odpowiedź na moje oryginalne pytanie. – bjornarneson

13

Można użyć 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) 

daje

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

Na marginesie, nie potrzebujesz 'np .inf' jako drugi argument. Domyślnie jest to None, co w tym przypadku jest równoważne. Jeśli obawiasz się czytelności, pozostawiając drugi argument, możesz zamiast tego użyć 'df.value.clip_lower (0)'. –

+0

@JoeKington: Oh, dzięki! – unutbu

+0

Dla tego, co jest warte, założyłem, że 'pandas.DataFrame.clip' zachowuje się jak' numpy'. Zdałem sobie sprawę, że nie (i nie potrzebujesz drugiego argumentu) około 5 minut temu! :) –

10

Inną możliwością jest użycie numpy.maximum(). Moim zdaniem jest to bardziej zrozumiałe.

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

A także 2-3X szybciej.

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

Myślę, że to jest dobre, jedyną wadą jest to, że 'np.max! = Np.maximum' co czyni to źle mnemonicznie – maxymoo

0

Weźmy tylko wartości większe od zera, pozostawiając te, które są negatywne jak NaN (nie współpracuje z ramek z serii), a następnie przypisać.

df[df > 0].fillna(0)