同一列中不同格式的Pandas日期时间

wlwcrazw  于 2023-04-18  发布在  其他
关注(0)|答案(5)|浏览(118)

我有一个pandas数据框,它有两种不同格式的日期时间,例如:

3/14/2019 5:15:32 AM
2019-08-03 05:15:35
2019-01-03 05:15:33
2019-01-03 05:15:33
2/28/2019 5:15:31 AM
2/27/2019 11:18:39 AM

...
我尝试了各种格式,但得到错误like ValueError: unconverted data remains: AM
我想获得2019-02-28的格式并删除时间

wqnecbli

wqnecbli1#

您可以使用pd.to_datetime().dt.strftime()将整个列有效地转换为datetime对象,然后转换为字符串,Pandas智能地猜测日期格式:

df = pd.Series('''3/14/2019 5:15:32 AM
2019-08-03 05:15:35
2019-01-03 05:15:33
2019-01-03 05:15:33
2/28/2019 5:15:31 AM
2/27/2019 11:18:39 AM'''.split('\n'), name='date', dtype=str).to_frame()

print(pd.to_datetime(df.date).dt.strftime('%Y-%m-%d'))
0    2019-03-14
1    2019-08-03
2    2019-01-03
3    2019-01-03
4    2019-02-28
5    2019-02-27
Name: date, dtype: object

如果这不能给予你想要的,你将需要识别不同类型的格式,并在将它们转换为datetime对象时应用不同的设置:

# Classify date column by format type
df['format'] = 1
df.loc[df.date.str.contains('/'), 'format'] = 2
df['new_date'] = pd.to_datetime(df.date)

# Convert to datetime with two different format settings
df.loc[df.format == 1, 'new_date'] = pd.to_datetime(df.loc[df.format == 1, 'date'], format = '%Y-%d-%m %H:%M:%S').dt.strftime('%Y-%m-%d')
df.loc[df.format == 2, 'new_date'] = pd.to_datetime(df.loc[df.format == 2, 'date'], format = '%m/%d/%Y %H:%M:%S %p').dt.strftime('%Y-%m-%d')
print(df)
date  format    new_date
0   3/14/2019 5:15:32 AM       2  2019-03-14
1    2019-08-03 05:15:35       1  2019-03-08
2    2019-01-03 05:15:33       1  2019-03-01
3    2019-01-03 05:15:33       1  2019-03-01
4   2/28/2019 5:15:31 AM       2  2019-02-28
5  2/27/2019 11:18:39 AM       2  2019-02-27
disho6za

disho6za2#

假设DataFrame中的列名为DatStr
成功的关键是一个合适的转换函数,应用于每个日期字符串:

def datCnv(src):
    return pd.to_datetime(src)

然后,要创建一个真正的日期列,你需要做的就是调用:

df['Dat'] = df.DatStr.apply(datCnv)

打印DataFrame时,结果为:

DatStr                 Dat
0   3/14/2019 5:15:32 AM 2019-03-14 05:15:32
1    2019-08-03 05:15:35 2019-08-03 05:15:35
2    2019-01-03 05:15:33 2019-01-03 05:15:33
3    2019-01-03 05:15:33 2019-01-03 05:15:33
4   2/28/2019 5:15:31 AM 2019-02-28 05:15:31
5  2/27/2019 11:18:39 AM 2019-02-27 11:18:39

请注意,to_datetime函数足够聪明,可以识别每种情况下使用的实际日期格式。

dphi5xsq

dphi5xsq3#

我也遇到过类似的问题。幸运的是,每隔一行都会出现不同的格式。因此,我可以轻松地使用.iloc进行切片。然而,您也可以使用.loc和过滤器(检测每种格式)对系列进行切片。
然后你可以用pd.concat合并行。顺序将与DataFrame的其余部分相同(如果你分配了它)。如果有缺失的索引,它们将变成NaN,如果有重复的索引,pandas将引发错误。

df["datetime"] = pd.concat([
    pd.to_datetime(df["Time"].str.slice(1).iloc[1::2], format="%y-%m-%d %H:%M:%S.%f"),
    pd.to_datetime(df["Time"].str.slice(1).iloc[::2], format="%y-%m-%d %H:%M:%S"),
])
hvvq6cgz

hvvq6cgz4#

pandas〉= 2.0:to_datetime可以使用format='infer'推断多种日期时间格式

代表性示例:

df
                    Date
0   3/14/2019 5:15:32 AM
1    2019-08-03 05:15:35
2    2019-01-03 05:15:33
3    2019-01-03 05:15:33
4   2/28/2019 5:15:31 AM
5  2/27/2019 11:18:39 AM
6              1/05/2015
7            15 Jul 2009
8               1-Feb-15
9             12/08/2019

pd.to_datetime(df['Date'], format='mixed')

0   2019-03-14 05:15:32
1   2019-08-03 05:15:35
2   2019-01-03 05:15:33
3   2019-01-03 05:15:33
4   2019-02-28 05:15:31
5   2019-02-27 11:18:39
6   2015-01-05 00:00:00
7   2009-07-15 00:00:00
8   2015-02-01 00:00:00
9   2019-12-08 00:00:00
Name: Date, dtype: datetime64[ns]

请注意文档中的警告:
“mixed”,用来分别推断每个元素的格式。这是有风险的,你应该和dayfirst一起使用
在上面的示例数据中,月份和月份的日期非常清楚,但并非所有数据都是如此。如果您认为to_datetime不能可靠地推断日期,则可以根据日期是否总是在混合格式中的第一个添加dayfirst=True/False,或者找到其他手动方法(或者更好的是,修复数据源!)

vmdwslir

vmdwslir5#

我想这个答案有点晚了,但我发现了一个更简单的方法来做同样的事情

df["date"] = pd.to_datetime(df["date"], format='%Y-%d-%m %H:%M:%S', errors='ignore').astype('datetime64[D]') 
df["date"] = pd.to_datetime(df["date"], format='%m/%d/%Y %H:%M:%S %p', errors='ignore').astype('datetime64[D]')

相关问题