如何在数据框列中更改日期而不更改时间戳的时间?

时间:2017-04-12 14:01:40

标签: python pandas datetime timestamp

Python 3.6.0

我正在导入一个带有Unix时间戳的文件 我将它们转换为Pandas日期时间并且舍入到10分钟(12:00,12:10,12:20,......)

数据是在指定的时间段内收集的,但是来自不同的日期 对于我们的分析,我们希望在进行重新采样之前将所有日期更改为相同的日期。

目前我们有一个reduce_to_date,它是所有日期的目标。

current_date = pd.to_datetime('2017-04-05')  #This will later be dynamic
reduce_to_date = current_date - pd.DateOffset(days=7)

我试图找到一种简单的方法来改变系列中的日期而不改变时间 我试图避免使用.strftime()进行冗长的转换。

我几乎解决的一种方法是将reduce_to_datedf['Timestamp']差异添加到df['Timestamp']。但是,我试图使用.date()函数,它只适用于单个元素,而不适用于系列。

GOOD!

passed_df['Timestamp'][0] = passed_df['Timestamp'][0] + (reduce_to_date.date() - passed_df['Timestamp'][0].date())

不好

passed_df['Timestamp'][:] = passed_df['Timestamp'][:] + (reduce_to_date.date() - passed_df['Timestamp'][:].date())
  

属性错误:'系列'对象没有属性' date'

我可以使用循环:

x=1
for line in passed_df['Timestamp']:
    passed_df['Timestamp'][x] = line + (reduce_to_date.date() - line.date())
    x+=1

但这会引发警告:

  

C:\ Users \ elx65i5 \ Documents \ Lightweight Logging \ newmain.py:60:SettingWithCopyWarning:   尝试在DataFrame的切片副本上设置值   请参阅文档中的警告:http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

目标是让所有日期保持不变,但保留原始时间 如果我们可以简单地指定更换日期,那就太好了 如果我们可以使用数学并根据时间增量改变每个日期,同样如此 我们可以在不使用.strftime()或冗长的过程的情况下以矢量化的方式实现这一目标吗?

3 个答案:

答案 0 :(得分:2)

我认为您需要转换df['Timestamp'].dt.date to_datetime,因为date的输出为python date object,而不是pandas datetime object

df=pd.DataFrame({'Timestamp':pd.to_datetime(['2017-04-05 15:21:03','2017-04-05 19:10:52'])})
print (df)
            Timestamp
0 2017-04-05 15:21:03
1 2017-04-05 19:10:52

current_date = pd.to_datetime('2017-04-05')
reduce_to_date = current_date - pd.DateOffset(days=7)

df['Timestamp'] = df['Timestamp'] - reduce_to_date + pd.to_datetime(df['Timestamp'].dt.date)
print (df)
            Timestamp
0 2017-04-12 15:21:03
1 2017-04-12 19:10:52

答案 1 :(得分:2)

如果我理解正确,你可以简单地减去一个偏移量

passed_df['Timestamp'] -=  pd.offsets.Day(7)

演示

passed_df=pd.DataFrame(dict(
        Timestamp=pd.to_datetime(['2017-04-05 15:21:03', '2017-04-05 19:10:52'])
    ))

# Make sure your `Timestamp` column is datetime.
# Mine is because I constructed it that way.
# Use
# passed_df['Timestamp'] = pd.to_datetime(passed_df['Timestamp'])

passed_df['Timestamp'] -=  pd.offsets.Day(7)

print(passed_df)

            Timestamp
0 2017-03-29 15:21:03
1 2017-03-29 19:10:52

使用strftime
虽然这不是理想的,但我想说明一点,你绝对可以使用strftime。如果您的列是日期时间,则可以通过strftime日期访问者dt使用dt.strftime。您可以创建一个动态列,在其中指定目标日期,如下所示:

pd.to_datetime(passed_df.Timestamp.dt.strftime('{} %H:%M:%S'.format('2017-03-29')))

0   2017-03-29 15:21:03
1   2017-03-29 19:10:52
Name: Timestamp, dtype: datetime64[ns]

答案 2 :(得分:0)

在此处进一步添加其他解决方案。您可以使用.dt.roundfreq = "10T"参数进行四舍五入到10分钟的舍入。

df=pd.DataFrame({'Timestamp':pd.to_datetime(['2017-04-05 15:21:03','2017-04-05 19:10:52'])})

df['Timestamp'] -=  pd.offsets.Day(7)

df['Timestamp'] = df.Timestamp.dt.round(freq='10T')
print(df)


            Timestamp
0 2017-03-29 15:20:00
1 2017-03-29 19:10:00