np.where覆盖值

时间:2019-07-05 21:26:37

标签: python pandas numpy dataframe

我正在尝试使用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().

是否有更好的方法来解决此问题?

2 个答案:

答案 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'])]

您应该得到所需的东西:))