【问题标题】:subtract one day from a pandas dataframe date column从熊猫数据框日期列中减去一天
【发布时间】:2020-12-30 11:04:45
【问题描述】:

对不起,我缺乏 Pandas 和 datetime 能力。我已经尝试过,但有些东西似乎超出了我目前有限的技能范围。

我正在使用日期列 (FinalStartPunch),它键入 datetime64[ns],如果 Hour 为 0,则从 datetime64[ns] 列(日期)中减去一天。如果 FinalStartPunch 小时不是 0,则只需照原样复制日期列值。

样本数据:

date         FinalStartPunch
6/27/2015   27JUN2015:14:15:00
7/23/2015   23JUL2015:13:31:00
7/23/2015   23JUL2015:18:43:00
8/15/2015   15AUG2015:18:35:00
8/15/2015   15AUG2015:23:30:00
8/16/2015   16AUG2015:00:00:00
1/30/2016   30JAN2016:18:25:00
1/30/2016   30JAN2016:23:52:00
1/31/2016   31JAN2016:00:00:00
8/13/2016   13AUG2016:18:30:00
8/13/2016   13AUG2016:23:58:00
8/14/2016   14AUG2016:00:00:00
1/28/2017   28JAN2017:18:30:00
1/28/2017   28JAN2017:23:57:00
1/29/2017   29JAN2017:00:00:00

关键代码部分:

df['New'] = df['date'] - pd.Timedelta(1, unit='D')  ### This one works
print(df.dtypes)

conds = [df['FinalStartPunch'].dt.hour == 0, df['FinalStartPunch'].dt.hour > 0]

choices = [df['date'] - pd.Timedelta(1, unit='D'), df['date']]

df['Date1'] = np.select(conds, choices, default=0)

错误:无效的类型提升

df['New'] 在选择行中使用相同的代码,这似乎是导致错误的问题。

也许是一个 Numpy 问题,我需要一种不同的方法来做到这一点?

任何帮助 - 非常感谢。

【问题讨论】:

    标签: pandas datetime type-promotion


    【解决方案1】:

    您可以使用.dt.hour == 0np.where() 来识别小时为0 的行,并使用- pd.tseries.offsets.Day() 来减去一天。

    df['date'] = pd.to_datetime(df['date'])
    df['FinalStartPunch'] = pd.to_datetime(df['FinalStartPunch'], format='%d%b%Y:%H:%M:%S')
    df['Date1'] = df['FinalStartPunch'].where((df['FinalStartPunch'].dt.hour != 0),
                                                        df['date'] - pd.tseries.offsets.Day())
    df
    Out[37]: 
             date     FinalStartPunch               Date1
    0  2015-06-27 2015-06-27 14:15:00 2015-06-27 14:15:00
    1  2015-07-23 2015-07-23 13:31:00 2015-07-23 13:31:00
    2  2015-07-23 2015-07-23 18:43:00 2015-07-23 18:43:00
    3  2015-08-15 2015-08-15 18:35:00 2015-08-15 18:35:00
    4  2015-08-15 2015-08-15 23:30:00 2015-08-15 23:30:00
    5  2015-08-16 2015-08-16 00:00:00 2015-08-15 00:00:00
    6  2016-01-30 2016-01-30 18:25:00 2016-01-30 18:25:00
    7  2016-01-30 2016-01-30 23:52:00 2016-01-30 23:52:00
    8  2016-01-31 2016-01-31 00:00:00 2016-01-30 00:00:00
    9  2016-08-13 2016-08-13 18:30:00 2016-08-13 18:30:00
    10 2016-08-13 2016-08-13 23:58:00 2016-08-13 23:58:00
    11 2016-08-14 2016-08-14 00:00:00 2016-08-13 00:00:00
    12 2017-01-28 2017-01-28 18:30:00 2017-01-28 18:30:00
    13 2017-01-28 2017-01-28 23:57:00 2017-01-28 23:57:00
    14 2017-01-29 2017-01-29 00:00:00 2017-01-28 00:00:00
    

    【讨论】:

    • 谢谢。由于我的沟通不畅,这很有效,只需稍作改动。我还想知道为什么另一种方法不起作用。仍然必须弄清楚这个日期输入难题。很高兴从有才华的人那里得到帮助。
    • @user2016566 ,没问题!如果它帮助您解决,请接受。关于 np.slect,这通常对我有用,但我只在多个条件和结果中使用它。不知道为什么它不适用于一种条件和一种结果。
    【解决方案2】:
    df.loc[df['FinalStartPunch'].dt.hour == 0, 'FinalStartPunch'] = df['FinalStartPunch'] - pd.Timedelta(1, unit='D')
    

    您可以使用 .loc 搜索这些时间,然后减去日期。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-04
      • 2018-11-15
      • 1970-01-01
      • 2015-09-19
      • 2018-08-06
      相关资源
      最近更新 更多