我有一个数据框(df),需要创建一个新列,该列是price
和metric
(已经计算过的整型数)的乘积。
df['cost'] = df['price'] * metric if (df['status'] == 'online')
df['cost'] = 0 if df['status'] == 'offline'
True
等于1,False
等于0的特点。3 * True -> 3
3 * False -> 0
我们需要检查在 status
列中的值是否等于 online
。
df['cost'] = df['price'] * df['status'].eq('online') * metric
无论何时,status
为offline
时,cost
值为0。
上述解决方案的前提是您希望将offline
的值设为0。如果您想将offline
设为999,则可以在此处使用Series.where
。
df['cost'] = df['price'].mul(metric).where(df['status'].eq('online'), 999)
现在,将每个离线
的值设置为999
。
有用的链接:
您可以使用np.where
:
import numpy as np
df['cost'] = np.where(df['status']=='online', df['price']*metric, 0)
df['cost'] = 0
df.loc[df['status']== "online" , 'cost'] = df['price'] * metric
或者使用列表推导式:
df['cost'] = [df['price']*metric if status == 'online' else 0 for status in df['status']]
虽然这里所有的答案都可以解决你的问题,但使用np.where或np.select(已在上面的答案中展示)是最好的选择,因为它可以解决多个条件。
然而,如果数据包含nan值,则使用np.where和np.select的上述解决方案可能会给出错误的输出。
让我简化并解释一下这两个函数(np.select和pd.cut),以备将来参考。
df = pd.DataFrame({'status':['online','offline','away','busy',np.nan]})
df['price'] = 100
df
status price
0 online 100
1 offline 100
2 away 100
3 busy 100
4 NaN 100
假设你有4个条件:
status = online then df['cost'] =df['price']*metric
status = offline then df['cost'] = 0
status = away then df['cost'] = 1
status = busy then df['cost'] = 2
然后,您可以将所有这些条件简单地放在一个段落中,如下所示:
col = 'status'
conditions = [ df[col] == 'online' , (df[col] == 'offline') , (df[col]== 'away'), df[col] == 'busy']
options = [df['price']*metric, 0, 1, 2 ]
df['cost'] = np.select(conditions, options)
运行后。
status price cost
0 online 100 500
1 offline 100 0
2 away 100 1
3 busy 100 2
4 NaN 100 0
你可以观察到nan前面的值为0。为了解决这个问题,请使用:
df['cost'] = np.select(conditions, options,default = np.nan)
np.where
也被广泛使用。既然你已经回答了,我必须想出一些不同的东西。:p - Ch3steR