【问题标题】:Convert strings (having different formats) to datetime in Python在 Python 中将字符串(具有不同格式)转换为日期时间
【发布时间】:2021-08-08 22:17:25
【问题描述】:

我有以下数据框:

df= {'DateTime': {0: '2017-08-02T00:00:00Z', 1: '2017-08-02T00:00:00.050Z', 2: '2017-08 02T00:00:00.100Z', 3: '2017-08-02T00:00:00.150Z', 4: '2017-08-02T00:00:00.200Z', 5: '2017-08 02T00:00:00.250Z', 6: '2017-08-02T00:00:00.300Z', 7: '2017-08-02T00:00:00.350Z', 8: '2017-08 02T00:00:00.400Z', 9: '2017-08-02T00:00:00.450Z', 10: '2017-08-02T00:00:00.500Z', 11: '2017-08 02T00:00:00.550Z', 12: '2017-08-02T00:00:00.600Z', 13: '2017-08-02T00:00:00.650Z', 14: '2017-08 02T00:00:00.700Z', 15: '2017-08-02T00:00:00.750Z', 16: '2017-08-02T00:00:00.800Z', 17: '2017-08 02T00:00:00.850Z', 18: '2017-08-02T00:00:00.900Z', 19: '2017-08-02T00:00:00.950Z', 20: '2017-08-02T00:00:01Z'}}

我想将“DateTime”列转换为datetime 格式,但问题是字符串具有不同的模式。例如,第一行的格式为"%Y-%m-%dT%H:%M:%SZ",但第2-19行的格式为"%Y-%m-%dT%H:%M:%S.%fZ",第20行的格式为"%Y-%m-%dT%H:%M:%SZ"。这种列如何转换为日期时间?

【问题讨论】:

  • 您真的需要指定格式吗? df.DateTime.apply(pd.to_datetime) 没有任何格式设置似乎工作得很好......
  • 正确!但是输出就像 2017-08-02 00:00:00+00:00, 2017-08-02 00:00:00.050000+00:00, ...... +00 有没有问题: 00?
  • 我对日期时间对象没有太多经验,但我认为这不是问题,转换为日期时间后,您可以使用df.DateTime.dt.tz_localize(None) 摆脱时区。
  • @fsimonjetz 你应该添加这个作为答案 ;-) 接受的一个过于复杂的事情恕我直言。 +00:00 表示 UTC,因为您的输入中有一个 Z(格式是 ISO 8601 btw.,Z 代表祖鲁时间),所以这是绝对正确的。

标签: python pandas datetime


【解决方案1】:

也许……

很简单:

    import pandas as pd
    
    df = pd.DataFrame({'DateTime': {0: '2017-08-02T00:00:00Z', 1: '2017-08-02T00:00:00.050Z', 2: '2017-08 02T00:00:00.100Z', 3: '2017-08-02T00:00:00.150Z', 4: '2017-08-02T00:00:00.200Z', 5: '2017-08 02T00:00:00.250Z', 6: '2017-08-02T00:00:00.300Z', 7: '2017-08-02T00:00:00.350Z', 8: '2017-08 02T00:00:00.400Z', 9: '2017-08-02T00:00:00.450Z', 10: '2017-08-02T00:00:00.500Z', 11: '2017-08 02T00:00:00.550Z', 12: '2017-08-02T00:00:00.600Z', 13: '2017-08-02T00:00:00.650Z', 14: '2017-08 02T00:00:00.700Z', 15: '2017-08-02T00:00:00.750Z', 16: '2017-08-02T00:00:00.800Z', 17: '2017-08 02T00:00:00.850Z', 18: '2017-08-02T00:00:00.900Z', 19: '2017-08-02T00:00:00.950Z', 20: '2017-08-02T00:00:01Z'}})
    
    df['DateTime'] = pd.to_datetime(df['DateTime']).dt.tz_localize(None)

或者:

    import pandas as pd
    from dateutil.parser import parse
    
    df = pd.DataFrame({'DateTime': {0: '2017-08-02T00:00:00Z', 1: '2017-08-02T00:00:00.050Z', 2: '2017-08 02T00:00:00.100Z', 3: '2017-08-02T00:00:00.150Z', 4: '2017-08-02T00:00:00.200Z', 5: '2017-08 02T00:00:00.250Z', 6: '2017-08-02T00:00:00.300Z', 7: '2017-08-02T00:00:00.350Z', 8: '2017-08 02T00:00:00.400Z', 9: '2017-08-02T00:00:00.450Z', 10: '2017-08-02T00:00:00.500Z', 11: '2017-08 02T00:00:00.550Z', 12: '2017-08-02T00:00:00.600Z', 13: '2017-08-02T00:00:00.650Z', 14: '2017-08 02T00:00:00.700Z', 15: '2017-08-02T00:00:00.750Z', 16: '2017-08-02T00:00:00.800Z', 17: '2017-08 02T00:00:00.850Z', 18: '2017-08-02T00:00:00.900Z', 19: '2017-08-02T00:00:00.950Z', 20: '2017-08-02T00:00:01Z'}})
    
    df['DateTime'] = df['DateTime'].apply(lambda x: parse(x))
    df['DateTime'] = df['DateTime'].apply(lambda x: x.strftime('%Y-%m-%d %H:%M:%S.%f'))

或者:

import pandas as pd
import dateparser

df['DateTime'] = df['DateTime'].apply(lambda x: dateparser.parse(x).strftime('%Y-%m-%d %H:%M:%S.%f'))

输出:

    DateTime
0   2017-08-02 00:00:00.000000
1   2017-08-02 00:00:00.050000
2   2017-08-02 00:00:00.100000
3   2017-08-02 00:00:00.150000
4   2017-08-02 00:00:00.200000
5   2017-08-02 00:00:00.250000
6   2017-08-02 00:00:00.300000
7   2017-08-02 00:00:00.350000
8   2017-08-02 00:00:00.400000
9   2017-08-02 00:00:00.450000
10  2017-08-02 00:00:00.500000
11  2017-08-02 00:00:00.550000
12  2017-08-02 00:00:00.600000
13  2017-08-02 00:00:00.650000
14  2017-08-02 00:00:00.700000
15  2017-08-02 00:00:00.750000
16  2017-08-02 00:00:00.800000
17  2017-08-02 00:00:00.850000
18  2017-08-02 00:00:00.900000
19  2017-08-02 00:00:00.950000
20  2017-08-02 00:00:01.000000

【讨论】:

  • 我认为这过于复杂了。一个简单的df['DateTime'] = pd.to_datetime(df['DateTime']) 就可以了。如果您不想指定时区,请本地化为无 (.dt.tz_localize(None))。
  • Np。添加了使其可用的选项。
  • 感谢更新,我会把它作为第一个选项 ^^ 顺便说一句。我没有投反对票。
  • 完成。目前投票率为50/50。一个真正的 Marmite 答案。
【解决方案2】:

一种选择是尝试分别转换每种格式,然后合并结果:

formats = ["%Y-%m-%dT%H:%M:%SZ", "%Y-%m-%dT%H:%M:%S.%fZ", "%Y-%m %dT%H:%M:%S.%fZ"]
parsed_dt = pd.to_datetime(df.DateTime, format=formats[0], errors='coerce')
for format in formats[1:]:
    parsed_dt = parsed_dt.fillna(pd.to_datetime(df.DateTime, format=format, errors='coerce'))

parsed_dt
0    2017-08-02 00:00:00.000
1    2017-08-02 00:00:00.050
2    2017-08-02 00:00:00.100
3    2017-08-02 00:00:00.150
4    2017-08-02 00:00:00.200
5    2017-08-02 00:00:00.250
6    2017-08-02 00:00:00.300
7    2017-08-02 00:00:00.350
8    2017-08-02 00:00:00.400
9    2017-08-02 00:00:00.450
10   2017-08-02 00:00:00.500
11   2017-08-02 00:00:00.550
12   2017-08-02 00:00:00.600
13   2017-08-02 00:00:00.650
14   2017-08-02 00:00:00.700
15   2017-08-02 00:00:00.750
16   2017-08-02 00:00:00.800
17   2017-08-02 00:00:00.850
18   2017-08-02 00:00:00.900
19   2017-08-02 00:00:00.950
20   2017-08-02 00:00:01.000
Name: DateTime, dtype: datetime64[ns]

【讨论】:

    猜你喜欢
    • 2021-04-02
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-10
    • 1970-01-01
    相关资源
    最近更新 更多