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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.