JeeyCi
JeeyCi

Reputation: 579

DataFrame: IF-condition in lambda asks about Series, but single element is needed to be checked

import numpy as np
import pandas as pd

#create DataFrame
df = pd.DataFrame({'str': [700,705,710,715,720,1095,1100,1105,1110,1115,1120,1125,1130,1135,1205,1210,1215,1220,1225,1230,1235,1240,1245,1250,1255],
 'P': [0.075,0.075,0.075,0.075,0.075,17.95,19.75,21.85,24.25,26.55,29.2,31.9,35.05,37.7,98.6,102.15,108.5,113.5,118.4,123.55,127.3,132.7,138.7,142.7,148.35],
 'C': [407.8,403.65,398.3,391.65,387.8,30.05,26.65,23.7,21.35,19.65,16.05,14.3,11.95,9.95,0.475,0,0.525,0,0.2,0.175,0.15,0.375,0.125,0.075,0.175]})

df = df.assign(ot= lambda x: x['P']  if (x['str']<1105) else x['C'])
print(df)

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

I suppose, x['str'] is being taken as Series, thus perhaps the index of the current row is needed, though it seems strange as so as "lambda x" I think should include only current row index & not the whole x['str'] Series. HOW to make condition "x['str']<1105" to be checked in such a lambda correctly??

Upvotes: 0

Views: 46

Answers (3)

Robinho
Robinho

Reputation: 21

You could simply use .where like so:

df['ot'] = df['P'].where(df['str'] < 1105, df['C'])

The .where() method takes two arguments: a condition, and a value to use if the condition is false. In this case, the condition is df['str'] < 1105, which checks whether the corresponding value in the 'str' column is less than 1105 for each row. If the condition is true, then the .where() method uses the value from the 'P' column, and if the condition is false, then it uses the value from the 'C' column. It basically overwrites the value of P with the value of C in the cases where the condition is false. In the cases where the condition is true, i.e. 'not false', it remains P.

See the documentation for .where: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.where.html

Upvotes: 2

JeeyCi
JeeyCi

Reputation: 579

also Solution from here:

df['ot'] = df[['P','C', 'str']].apply(lambda x: x['P'] if x['str']<1105 else x['C'], axis=1)

or simply df.apply(...)

Upvotes: 0

Charles Yang
Charles Yang

Reputation: 344

I think you're looking for this:

result_list = [(x['P'] if (x['str'] < 1105) else x['C']) for i, x in df.iterrows()]

Upvotes: 1

Related Questions