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

时间:2019-03-19 17:44:41

标签: python pandas datetime

我有一个熊猫数据框,其日期时间具有2种不同的格式,例如:

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并删除时间

3 个答案:

答案 0 :(得分:1)

您可以使用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

如果这样不能满足您的需求,则在将它们转换为日期时间对象时,您将需要识别不同类型的格式并应用不同的设置:

# 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

答案 1 :(得分:0)

假设您的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函数足够聪明,可以识别 每种情况下使用的实际日期格式。

答案 2 :(得分:0)

我遇到了类似的问题。幸运的是,不同的格式每隔一行出现一次。因此,我可以轻松地使用 .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"),
])