1

I want to create a new column that returns a value if it matches criteria is both columns of an existing df.

df = pd.DataFrame({
  'first_column': [1, 2, 3, 5],
  'second_column': [10, 20, 30, 50]
})

df.loc[df.first_column <= 3, 'new_column'] = 'good'
df.loc[df.first_column == 1, 'new_column'] = 'bad'
df.loc[df.first_column >= 4, 'new_column'] = 'great'

This works for one condition (though I assume there is a way to say between 2 and 3 which is what I really want for the first line)

But I can't figure out how to get it do so something where I could say if df.first_column >= 4 AND df.second_column >= 50 = 'super great'

showdev
  • 28,454
  • 37
  • 55
  • 73
amanda
  • 99
  • 1
  • 3
  • Possible duplicate of [Efficient way to apply multiple filters to pandas DataFrame or Series](https://stackoverflow.com/questions/13611065/efficient-way-to-apply-multiple-filters-to-pandas-dataframe-or-series) – NickHilton Oct 17 '19 at 21:55

1 Answers1

1

Method 1: pd.cut

What you want is pd.cut, to assign 'labels' to certain 'ranges' in this case called bins:

df['new_column'] = pd.cut(df['first_column'],
                   bins=[-np.inf, 1,3,50, np.inf],
                   labels=['bad', 'good', 'great', 'supergreat'])

   first_column  second_column new_column
0             1             10        bad
1             2             20       good
2             3             30       good
3             5             50      great

Method 2: np.select:

We can also use numpy.select which takes multiple conditions and based on those conditions it returns a value (choice):

conditions = [
    df['first_column'] <= 1,
    df['first_column'].between(1, 3),
    (df['first_column'] >= 4) & (df['second_column'] >= 50),
    df['first_column'] >= 4
]

choices = ['bad', 'good', 'supergreat', 'great']

df['new_column'] = np.select(conditions, choices)

   first_column  second_column  new_column
0             1             10         bad
1             2             20        good
2             3             30        good
3             5             50  supergreat
Erfan
  • 40,971
  • 8
  • 66
  • 78