【问题标题】:changing relative times to actual dates in a pandas dataframe在熊猫数据框中将相对时间更改为实际日期
【发布时间】:2018-04-25 01:28:57
【问题描述】:

我目前有一个通过抓取谷歌新闻标题创建的数据框。我的一个专栏是“时间”,它指的是一篇文章的发表时间。

很遗憾,对于最近的文章,Google 新闻使用“相对”日期,例如 6 小时前或 1 天前,而不是 2017 年 11 月 1 日。

我真的想将这些相对日期转换为与其他条目一致(例如,他们也说 2017 年 11 月 12 日),但我什至不知道从哪里开始。

我的想法是创建一个代表今天日期的变量,然后通过数据框搜索与我的格式不匹配的内容,然后用当前日期减去这些相对时间。我还必须为“几小时前”的内容制作某种过滤器,并让它们与当前日期相同。

我并不是真的想要一个解决方案,而是想大致了解要阅读什么来尝试解决这个问题。我应该尝试使用 numpy 吗?

一些行的例子:

     Publication    Time    Headline
0   The San Diego Union-Tribune     6 hours ago     I am not opposed to new therapeutic modalities...
1   Devon Live  13 hours ago    If you're looking for a bargain this Christmas...
15  ABS-CBN News    1 day ago   Now, Thirdy has a chance to do something that ...
26  New York Times  Nov 2, 2017     Shepherds lead their sheep through the centre ...

【问题讨论】:

  • 请添加示例数据框
  • 抱歉 - 刚刚编辑!
  • 让“几小时前”等于当前日期,如果它回到昨天,会给你带来麻烦。最好使用您为所有情况描述的方法转换为日期时间格式。
  • 哦...你是对的。这会产生一些问题。我想我需要知道现在的时间和日期然后减去

标签: python pandas datetime dataframe


【解决方案1】:

您的方法应该有效。使用 Pandas Timedelta 从当前日期中减去相对日期。

例如,假设您的示例数据为:

Publication;Time;Headline
The San Diego Union-Tribune;6 hours ago;I am not opposed to new therapeutic modalities
Devon Live;13 hours ago;If you're looking for a bargain this Christmas
ABS-CBN News;1 day ago;Now, Thirdy has a chance to do something that
New York Times;Nov 2, 2017;Shepherds lead their sheep through the centre

从剪贴板中读取数据(尽管您可以轻松地用read_csv() 或其他文件格式替换):

import pandas as pd
from datetime import datetime

df = pd.read_clipboard(sep=";")

对于已经是日期格式的日期,Pandas 很聪明,可以用to_datetime() 进行转换:

absolute_date = pd.to_datetime(df.Time, errors="coerce")

absolute_date
0          NaT
1          NaT
2          NaT
3   2017-11-02
Name: Time, dtype: datetime64[ns]

对于相对日期,一旦我们删除“之前”部分,它们基本上是正确的格式,可以使用pd.Timedelta 进行转换:

relative_date = (datetime.today() - 
                 df.Time.str.extract("(.*) ago", expand=False).apply(pd.Timedelta))

relative_date
0   2017-11-11 17:05:54.143548
1   2017-11-11 10:05:54.143548
2   2017-11-10 23:05:54.143548
3                          NaT
Name: Time, dtype: datetime64[ns]

现在填写每个集合中的相应 NaN 值,绝对值和相对值(更新为使用 combine_first(),通过 Jezrael 的回答):

date = relative_date.combine_first(absolute_date)

relative_date
0   2017-11-11 17:06:29.658925
1   2017-11-11 10:06:29.658925
2   2017-11-10 23:06:29.658925
3   2017-11-02 00:00:00.000000
Name: Time, dtype: datetime64[ns]

最后,只从 datetime 中取出日期:

date.dt.date
0    2017-11-11
1    2017-11-11
2    2017-11-10
3    2017-11-02
Name: Time, dtype: object

【讨论】:

  • 非常感谢!这非常简单——我不知道 pandas 已经有了这个功能。
【解决方案2】:

您可以先将to_datetimeto_timedelta 一起使用,然后再将combine_firstfloor 一起使用:

#create dates
dates = pd.to_datetime(df['Time'], errors='coerce')
#create times
times = pd.to_timedelta(df['Time'].str.extract('(.*)\s+ago', expand=False))
#combine final datetimes
df['Time'] = (pd.datetime.now() - times).combine_first(dates).dt.floor('D')

print (df)
                   Publication       Time  \
0  The San Diego Union-Tribune 2017-11-12   
1                   Devon Live 2017-11-11   
2                 ABS-CBN News 2017-11-11   
3               New York Times 2017-11-02   

                                         Headline  
0  I am not opposed to new therapeutic modalities  
1  If you're looking for a bargain this Christmas  
2   Now, Thirdy has a chance to do something that  
3   Shepherds lead their sheep through the centre  

print (df['Time'])
0   2017-11-12
1   2017-11-11
2   2017-11-11
3   2017-11-02
Name: Time, dtype: datetime64[ns]

【讨论】:

  • combine_first() 对我来说是新的,谢谢你的课程。
猜你喜欢
  • 2017-05-21
  • 1970-01-01
  • 2019-01-24
  • 2019-09-19
  • 2020-03-14
  • 1970-01-01
  • 2019-07-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多