Try:
(df['A'] + df['B']).where((df['A'] < 0) | (df['B'] > 0), df['A'] / df['B'])
The difference between the numpy where and DataFrame where is that the default values are supplied by the DataFrame that the where method is being called on (docs).
I.e.
np.where(m, A, B)
is roughly equivalent to
A.where(m, B)
If you wanted a similar call signature using pandas, you could take advantage of the way method calls work in Python:
pd.DataFrame.where(cond=(df['A'] < 0) | (df['B'] > 0), self=df['A'] + df['B'], other=df['A'] / df['B'])
or without kwargs (Note: that the positional order of arguments is different from the numpy where argument order):
pd.DataFrame.where(df['A'] + df['B'], (df['A'] < 0) | (df['B'] > 0), df['A'] / df['B'])
Answer from Alex on Stack OverflowTry:
(df['A'] + df['B']).where((df['A'] < 0) | (df['B'] > 0), df['A'] / df['B'])
The difference between the numpy where and DataFrame where is that the default values are supplied by the DataFrame that the where method is being called on (docs).
I.e.
np.where(m, A, B)
is roughly equivalent to
A.where(m, B)
If you wanted a similar call signature using pandas, you could take advantage of the way method calls work in Python:
pd.DataFrame.where(cond=(df['A'] < 0) | (df['B'] > 0), self=df['A'] + df['B'], other=df['A'] / df['B'])
or without kwargs (Note: that the positional order of arguments is different from the numpy where argument order):
pd.DataFrame.where(df['A'] + df['B'], (df['A'] < 0) | (df['B'] > 0), df['A'] / df['B'])
pandas 2.2 update: Series.case_when
From pandas 2.2.0, the API provides a pandaic alternative to np.where and np.select.
Using case_when:
cond = (df['A'] < 0) | (df['B'] > 0)
df['C'] = (df['A'] / df['B']).case_when([(cond, df['A'] + df['B'])])
# or
df['C'] = 0 # Or pd.NA or any reasonable default.
df['C'] = df['C'].case_when([(cond, df['A'] + df['B']),
(~cond, df['A'] / df['B']),
])
You notice that case_when allows you to provide an arbitrary list of conditions and replacement pairs, so this can generalize to several conditions easily (much like np.select).
Using np.where:
df['C'] = np.where((df['A'] < 0) | (df['B'] > 0), df['A'] + df['B'], df['A'] / df['B'])
Think of loc as a filter - give me only the parts of the df that conform to a condition.
where originally comes from numpy. It runs over an array and checks if each element fits a condition. So it gives you back the entire array, with a result or NaN. A nice feature of where is that you can also get back something different, e.g. df2 = df.where(df['Goals']>10, other='0'), to replace values that don't meet the condition with 0.
ID Run Distance Goals Gender
0 1 234 12 m
1 2 35 23 m
2 3 77 56 m
3 0 0 0 0
4 0 0 0 0
5 0 0 0 0
6 0 0 0 0
7 0 0 0 0
8 0 0 0 0
9 10 123 34 m
Also, while where is only for conditional filtering, loc is the standard way of selecting in Pandas, along with iloc. loc uses row and column names, while iloc uses their index number. So with loc you could choose to return, say, df.loc[0:1, ['Gender', 'Goals']]:
Gender Goals
0 m 12
1 m 23
locretrieves only the rows that matches the condition.wherereturns the whole dataframe, replacing the rows that don't match the condition (NaN by default).