1

I can't seem to figure out how to do this in one step. I want to set the even entries to 1 and the odd ones to -1:

df = DataFrame(np.arange(16).reshape(4,4))
x1 = df.where(df%2==0, -1)
x2 = x1.where(df%2!=0, 1)

The docs for pandas.DataFrame.where say:

Return an object of same shape as self and whose corresponding entries are from self where cond is True and otherwise are from other.

So is this the only way?

3 Answers 3

1

We could use np.where to use the boolean condition to set the values where true and to set the value to the alternate value when false. This will return a numpy array which if you want as a df you have to pass as an arg to the df ctor:

In [31]:

df = pd.DataFrame(np.where(df%2==0,-1,1))
df
Out[31]:
   0  1  2  3
0 -1  1 -1  1
1 -1  1 -1  1
2 -1  1 -1  1
3 -1  1 -1  1
Sign up to request clarification or add additional context in comments.

2 Comments

I guess what my question really is is: why can we do this with a numpy array but not with a dataframe?
Probably because pandas is always slightly SQL-ish and the SQL WHERE statement returns the original values of the database?
1

numpy.choose can be useful here.

from pandas import DataFrame
import numpy as np
df = DataFrame(np.arange(16).reshape(4,4))
np.choose(df%2, [1, -1])
=> 
   0  1  2  3
0  1 -1  1 -1
1  1 -1  1 -1
2  1 -1  1 -1
3  1 -1  1 -1

The second arg is the list of values to replace with. The value at index=0 replaces where values==0, etc.

3 Comments

Isn't this backwards?
@DSM, well, it's a way to do it in one step (and a rather fast one too). Not necessarily readable nor intuitive, I'd give you that...
@DSM, I'm actually glad I interpreted your comment the way I did :) but thanks for pointing out.
1

For the whole dataframe, in one line:

In [34]: df = pd.DataFrame(randint(0,8,size=(3,3)))

In [35]: df
Out[35]: 
   0  1  2
0  3  4  1
1  3  3  1
2  7  7  3

In [37]: df = ((df%2)-0.5)*-2

In [38]: df
Out[38]: 
   0  1  2
0 -1  1 -1
1 -1 -1 -1
2 -1 -1 -1

By column:

df = pd.DataFrame([list('addfg'),list('LKJHU')]).T
df.Odds = ((df.index.values%2)-0.5)*-2

result:

   0  1  Odds
0  a  L     1
1  d  K    -1
2  d  J     1
3  f  H    -1
4  g  U     1

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.