我正在尝试使用np.where从熊猫数据框中的其他两个列创建派生列。
df['END_TIME'] = np.where(((df['TYPE'] == 'BOLUS') & (df['DESCRIPTION'] == 'rocuronium')), df['START_TIME'] + dt.timedelta(minutes=30), None)
df['END_TIME'] = np.where(((df['TYPE'] == 'BOLUS') & (df['DESCRIPTION'] == 'vecuronium')), df['START_TIME'] + dt.timedelta(minutes=45), None)
但是发生的是当我运行np.where条件的第二行时,它清除了第一个np.where的第一个结果值。
DESCRIPTION TYPE START_TIME
rocuronium BOLUS 2018-04-26 05:32:00
rocuronium BOLUS 2018-04-26 05:38:00
vecuronium NOT BOLUS 2018-04-26 14:59:59
vecuronium NOT BOLUS 2018-04-26 15:59:59
vecuronium BOLUS 2018-04-27 07:50:00
这是实际的数据框,现在我尝试根据类型和描述创建一个新的派生列。当我运行第一个np.where语句时,结果数据帧将是:
DESCRIPTION TYPE START_TIME END_TIME
rocuronium BOLUS 2018-04-26 05:32:00 2018-04-26 06:02:00
rocuronium BOLUS 2018-04-26 05:38:00 2018-04-26 06:08:00
vecuronium NOT BOLUS 2018-04-26 14:59:59
vecuronium NOT BOLUS 2018-04-26 15:59:59
vecuronium BOLUS 2018-04-27 07:50:00
哪个好。但是,如果我运行第二个np.where语句,则结果数据帧看起来像。
DESCRIPTION TYPE START_TIME END_TIME
rocuronium BOLUS 2018-04-26 05:32:00
rocuronium BOLUS 2018-04-26 05:38:00
vecuronium NOT BOLUS 2018-04-26 14:59:59 None
vecuronium NOT BOLUS 2018-04-26 15:59:59 None
vecuronium BOLUS 2018-04-27 07:50:00 2018-04-27 08:35:00
我不知道为什么我丢失了第一个np.where语句数据。
预期的数据框:
DESCRIPTION TYPE START_TIME END_TIME
rocuronium BOLUS 2018-04-26 05:32:00 2018-04-26 06:02:00
rocuronium BOLUS 2018-04-26 05:38:00 2018-04-26 06:08:00
vecuronium NOT BOLUS 2018-04-26 14:59:59 None
vecuronium NOT BOLUS 2018-04-26 15:59:59 None
vecuronium BOLUS 2018-04-27 07:50:00 2018-04-27 08:35:00
我试图创建以下函数并调用它:
def add_roc(df):
if (df['TYPE'] == 'BOLUS') & (df['DESCRIPTION'] == 'rocuronium'):
df['END_TIME'] = df['START_TIME'] + dt.timedelta(minutes=30)
return df
并引发以下错误:
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
是否有更好的方法来解决此问题?
答案 0 :(得分:2)
将np.select
用于多个条件。对于许多情况,这将很好地推广。 pd.to_datetime
是因为事物被强制为int。
import numpy as np
import pandas as pd
cond_lst = [df['TYPE'].eq('BOLUS') & df['DESCRIPTION'].eq('rocuronium'),
df['TYPE'].eq('BOLUS') & df['DESCRIPTION'].eq('vecuronium')]
choice_lst = [df['START_TIME']+pd.Timedelta(minutes=30),
df['START_TIME']+pd.Timedelta(minutes=45)]
df['END_TIME'] = pd.to_datetime(np.select(cond_lst, choice_lst, default=pd.NaT))
DESCRIPTION TYPE START_TIME END_TIME
0 rocuronium BOLUS 2018-04-26 05:32:00 2018-04-26 06:02:00
1 rocuronium BOLUS 2018-04-26 05:38:00 2018-04-26 06:08:00
2 vecuronium NOT BOLUS 2018-04-26 14:59:59 NaT
3 vecuronium NOT BOLUS 2018-04-26 15:59:59 NaT
4 vecuronium BOLUS 2018-04-27 07:50:00 2018-04-27 08:35:00
在这种情况下,由于'TYPE'
列中的二分变量,我建议使用where
+ map
。
d = {'rocuronium': pd.Timedelta(minutes=30),
'vecuronium': pd.Timedelta(minutes=45)}
df['END_TIME'] = df['START_TIME'].where(df.TYPE.eq('BOLUS')) + df.DESCRIPTION.map(d)
答案 1 :(得分:0)
尝试一下:
df = df.loc[df['DESCRIPTION'].isin(['rocuronium'])]
df = df.loc[df['TYPE'].isin(['BOLUS'])]
您应该得到所需的东西:))