【问题标题】:np.where condition first instance ok, second instance throws errornp.where 条件第一个实例正常,第二个实例抛出错误
【发布时间】:2020-02-06 04:04:45
【问题描述】:

我有一个 pandas 数据框,其中有一个日期列,其中包含日期优先('欧洲')和月份优先(美国)日期的日期。我有一个单独的 int 类型的列,其中包含“年份”值。 df.year2017 的日期字符串是天优先的。

我正在使用 np.where 条件将日期字符串中的月份和日期分隔到单独的列中,以在此后构建日期时间。所以我有这个数据:

'year' 'number' 'date'
2016    75  01/05/2017 00:00
2016    75  01/06/2017 00:00
2016    75  01/06/2017 00:00
2016    75  01/06/2017 00:00
2016    75  01/06/2017 00:00
2016    75  01/09/2017 00:00
2016    75  01/09/2017 00:00
2016    75  01/10/2017 00:00
2016    75  01/10/2017 00:00
2017    0   01/01/2017 00:00
2017    0   01/01/2017 00:00
2017    0   01/01/2017 00:00
2017    0   01/01/2017 00:00
2017    0   02/01/2017 00:00
2017    0   03/01/2017 00:00
2017    0   04/01/2017 00:00
2017    0   04/01/2017 00:00
2017    0   04/01/2017 00:00
2017    0   04/01/2017 00:00
2017    0   05/01/2017 00:00

我已经使用它来创建月份值:

df['dt_mo'] = np.where(df.year<2017,df.date.str.extract(r'(\d+)\/\d+\/\d+'), df.date.str.extract(r'\d+\/(\d+)\/\d+'))

这可以很好地删除月份。我也尝试过其他方法,但是由于 ['year'] 是 type(int) 这工作正常

但是,当我尝试执行类似的过程来提取日期值时,它会引发错误。

我尝试过翻转大于/小于运算符以及交换捕获组。

(1)sl['dt_dy'] = np.where(sl.year>2017, sl.date.str.extract(r'(\d+)\/\d+\/\d+'),sl.date.str.extract(r'\d+\/(\d+)\/\d+'))

或

(2)df['dt_dy'] = np.where(df.year<2017,df.date.str.extract(r'\d+\/(\d+)\/\d+'), df.date.str.extract(r'(\d+)\/\d+\/\d+'))

两者都返回以下常见错误,“ValueError: Wrong number of items passed 2, placement 暗示 1”。

理想情况下,df.dt_dy 会以与 df.dt_mo 当前返回月份数字值相同的方式返回日期数字值。

一如既往地更喜欢任何更清洁的方法

谢谢

【问题讨论】:

    标签: pandas numpy


    【解决方案1】:

    看来您最终想要制作datetime,所以从一开始就创建它,并指定不同的格式np.where。如果您需要这些日子,您现在可以使用 datetime 访问器。

    import numpy as np
    import pandas as pd
    
    df['my_date'] = np.where(df.year < 2017, 
                             pd.to_datetime(df.date, format='%m/%d/%Y %H:%M', errors='coerce'),
                             pd.to_datetime(df.date, format='%d/%m/%Y %H:%M', errors='coerce'))
    

        year  number              date    my_date
    0   2016      75  01/05/2017 00:00 2017-01-05
    1   2016      75  01/06/2017 00:00 2017-01-06
    2   2016      75  01/06/2017 00:00 2017-01-06
    3   2016      75  01/06/2017 00:00 2017-01-06
    4   2016      75  01/06/2017 00:00 2017-01-06
    5   2016      75  01/09/2017 00:00 2017-01-09
    6   2016      75  01/09/2017 00:00 2017-01-09
    7   2016      75  01/10/2017 00:00 2017-01-10
    8   2016      75  01/10/2017 00:00 2017-01-10
    9   2017       0  01/01/2017 00:00 2017-01-01
    10  2017       0  01/01/2017 00:00 2017-01-01
    11  2017       0  01/01/2017 00:00 2017-01-01
    12  2017       0  01/01/2017 00:00 2017-01-01
    13  2017       0  02/01/2017 00:00 2017-01-02
    14  2017       0  03/01/2017 00:00 2017-01-03
    15  2017       0  04/01/2017 00:00 2017-01-04
    16  2017       0  04/01/2017 00:00 2017-01-04
    17  2017       0  04/01/2017 00:00 2017-01-04
    18  2017       0  04/01/2017 00:00 2017-01-04
    19  2017       0  05/01/2017 00:00 2017-01-05
    

    【讨论】:

    • 太棒了!我还有另外 2 列零星的开始和结束时间。我可以将这些时间之一或两者都添加到已经创建的相应日期时间吗?
    • @jrbwt 是的。只要您将它们转换为timedelta 或datetime,那么您应该能够添加它们。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-02
    • 2015-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多