【问题标题】:Formatting datetime variables give missing time values as 00:00:00. Using Python格式化日期时间变量会将缺失的时间值设为 00:00:00。使用 Python
【发布时间】:2015-05-13 03:53:56
【问题描述】:

我目前正在使用 python 尝试将日期时间列拆分为 2 个,一个用于日期,一个用于时间,并且该列的格式也正确。

原始数据集

INCIDENT_DATE
12/31/2006 11:20:00 PM
12/31/2006 11:30:00 PM
01/01/2007 00:25
01/01/2007 00:10
12/31/2006 11:30:00 AM
01/01/2007 00:05
01/01/2007 00:01
12/31/2006 4:45:00 PM
12/31/2006 11:50:00 PM
**01/01/2007**

*我使用了 2 个代码,一个用于格式化列,另一个用于拆分它。但是,在格式化该列后,缺少的时间值给出了 00:00:00 值,这里表示时间为午夜 12 点。见下文

格式化后

2006-12-31 23:20:00
2006-12-31 23:30:00
2007-01-01 00:25:00
2007-01-01 00:10:00
2006-12-31 11:30:00
2007-01-01 00:05:00
2007-01-01 00:01:00
2006-12-31 16:45:00
2006-12-31 23:50:00
**2007-01-01 00:00:00**

使用的代码:

## Format datetime column
crimeall['INCIDENT_DATE'] = pd.DatetimeIndex(crimeall['INCIDENT_DATE'])

##Split DateTime column
crimeall['TIME'],crimeall['DATE']= crimeall['INCIDENT_DATE'].apply(lambda x:x.time()), crimeall['INCIDENT_DATE'].apply(lambda x:x.date())

是否可以在不将缺失时间值设置为 00:00:00 的情况下执行此操作?格式化日期时间时是否可以将这些缺失值记录为 Nan?

关于如何实现将缺失时间值显示为 NaN 的格式化日期时间的任何想法。

我希望它看起来像什么

2006-12-31 23:20:00
2006-12-31 23:30:00
2007-01-01 00:25:00
2007-01-01 00:10:00
2006-12-31 11:30:00
2007-01-01 00:05:00
2007-01-01 00:01:00
2006-12-31 16:45:00
2006-12-31 23:50:00
**2007-01-01 NaN**

希望有办法完成这项工作。

【问题讨论】:

  • 抱歉,您能否编辑您的问题,因为我不明白 ** 的用途。如果您使用的是最新版本的熊猫,您还可以发布您的真实原始输入数据,那么您应该可以,如果 INCIDENT_DATE 已经是日期时间 dtype,只需执行 crimeall['TIME'],crimeall['DATE']= crimeall['INCIDENT_DATE'].dt.time, crimeall['INCIDENT_DATE'].dt.date
  • 如果我正确理解您的问题,您的问题是您的日期字符串的格式不一致,因此当您构建 datetimeindex 或使用 pd.to_datetime 时,任何缺少的时间部分(或日期部分)问题)将提供默认值,之后您可以将00:00:00替换为NaT
  • 但是假设00:00:00NaT 是有问题的,因为它很可能是有效的。确定哪些值是有效的需要转换为日期时间之前完成。

标签: python datetime pandas


【解决方案1】:

ambiguous =‘NaT’ 添加到pd.DatetimeIndex。如果这不起作用,您可以随时使用类似的方法修补值

crimeall['TIME'] = [np.NaN if t.isoformat()=='00:00:00' else t for t in crimeall['TIME']]

【讨论】:

  • 你好 EdChurn 和 Ed Smith。感谢您的 cmets,抱歉有点不清楚,我是 python 和 pandas 的新手。您说得对,日期字符串不一致,并且在构造 datetimeindex 时,默认值(缺失值)为 00:00:00。我不能用'NaT'替换这些,因为我也有00:00:00的实时值。如果这可能会有所不同,我还将它们拆分为“日期”和“时间”。 '**' 只是为了引起对特定实例的注意。很抱歉造成混乱。再次感谢您的帮助。
  • 另外,** 指的是缺少时间的数据时间列。
  • 不是很优雅,但是如果您从字符串列开始,您可以在仅提供日期的情况下在第一步创建一个值为 1 的变量,例如:crimeall['HOUR_MISSING'] = crimeall['INCIDENT_DATE'].apply(lambda x: 1 if re.match('^[0-9]{2}/[0-9]{2}/[0-9]{4}$', x) else 0)
【解决方案2】:

我不相信有任何方法可以拥有一个部分有效且部分为 NaN 的类似日期时间的列。请注意,日期时间本质上是整数之上的一种格式,整数不能一半有效,一半缺失(下文会详细介绍)。

无论如何,我会在当时创建一个新专栏,而不是包含 NaN。从以下开始,其中“raw_dt”是您的原始数据,“formatted_dt”是正确的日期时间:

                   raw_dt        formatted_dt
0  12/31/2006 11:20:00 PM 2006-12-31 23:20:00
1  12/31/2006 11:30:00 PM 2006-12-31 23:30:00
...
7   12/31/2006 4:45:00 PM 2006-12-31 16:45:00
8  12/31/2006 11:50:00 PM 2006-12-31 23:50:00
9              01/01/2007 2007-01-01 00:00:00

我会创建一个面具,像这样:

df['valid_time'] = df.raw_dt.str.contains(':')

在这里应该可以正常工作,如果您需要更复杂的东西,可以使用正则表达式。然后新建一个时间列。

df['time'] = df.ix[df['valid_time'],'formatted_dt'].dt.time

                   raw_dt        formatted_dt valid_time      time
0  12/31/2006 11:20:00 PM 2006-12-31 23:20:00       True  23:20:00
1  12/31/2006 11:30:00 PM 2006-12-31 23:30:00       True  23:30:00
...
7   12/31/2006 4:45:00 PM 2006-12-31 16:45:00       True  16:45:00
8  12/31/2006 11:50:00 PM 2006-12-31 23:50:00       True  23:50:00
9              01/01/2007 2007-01-01 00:00:00      False       NaN

从那里你可以随意格式化,例如:

df.formatted_dt.dt.date.map(str) + df.time.map(str).str.rjust(9)

0    2006-12-31 23:20:00
1    2006-12-31 23:30:00
...
7    2006-12-31 16:45:00
8    2006-12-31 23:50:00
9    2007-01-01      nan

要简要介绍什么是日期时间,请查看 here 并注意,您可以通过这样做来了解日期时间的真正含义(自 1970 年 1 月 1 日以来的纳秒):

df.formatted_dt.astype(np.int64)

0    1167607200000000000
1    1167607800000000000
...
7    1167583500000000000
8    1167609000000000000
9    1167609600000000000

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-25
    • 1970-01-01
    • 2018-03-23
    • 2017-04-12
    • 1970-01-01
    • 2013-07-23
    • 2016-06-04
    • 1970-01-01
    相关资源
    最近更新 更多