使用一些 Nan 来从 3 列(日期、时间、微秒)重建日期时间列

问题描述 投票:0回答:2

我有一个针对特定证券提交的订单的高频金融数据库(不幸的是我无法在这里分享)。每一行都是一个订单(新订单或订单更新)。对于每一行,有多个时间信息(一个“时间信息”为 3 列:日期、时间、微秒)。我的目标是创建一个将所有三部分信息结合起来的专栏。第一个也是容易处理的情况是订单提交。

日期列 (o_d_be) 的类型为 int(格式为 yyyymmdd),时间列 (o_t_be) 的类型为 object(格式为 hh:mm:ss),最后一列微秒 (o_m_be) 的类型为 int。所有时间信息都遵循这种模式。

我写道,订单提交很容易处理,因为没有缺失值,每个订单都必须在某个时间提交。对于这种情况,我编写了以下代码(可能可以改进):

data['o_d_be'] = data['o_d_be'].apply(lambda x: str(x))
    data['o_t_be'] = data['o_t_be'].apply(lambda x: str(x))
    data['o_dtm_be'] = pd.to_datetime(data['o_d_be'] + ' ' + data['o_t_be'], format='%Y%m%d %H:%M:%S') + pd.to_timedelta(data['o_m_be'], unit='us')

然而,当订单更新变得棘手时。首次提交订单时,专用列中没有更新的日期、时间、微秒。仅在更新已提交的订单后才会填充这些列(在这种情况下,订单提交时间列不会更改)。因此,由于 Nan 值,上面的代码不适用于这些列。

到目前为止,我已经尝试过以下方法:

data['o_d_mo'] = data['o_d_mo'].apply(lambda x: np.nan if x==np.nan else str(x))
data['o_t_mo'] = data['o_t_mo'].apply(lambda x: np.nan if x==np.nan else str(x))

data['o_dtm_mo'] = np.where(data['o_m_mo']==np.nan, np.nan, pd.to_datetime(data['o_d_mo'] + ' ' + data['o_t_mo'], format='%Y%m%d %H:%M:%S') + pd.to_timedelta(data['o_m_mo'], unit='us'))

但是,这样做时,我收到以下错误:

time data nan nan doesn't match format specified

对如何实现我的目标有什么想法吗? 预先感谢您!

python pandas datetime finance
2个回答
0
投票

试试这个,希望它有帮助,你必须像这样填写:

选项1:使用pandas mask

import pandas as pd
import numpy as np

# Convert 'o_d_be' and 'o_t_be' to string
data['o_d_be'] = data['o_d_be'].astype(str)
data['o_t_be'] = data['o_t_be'].astype(str)

# Convert 'o_d_be' and 'o_t_be' to datetime
data['o_dtm_be'] = pd.to_datetime(data['o_d_be'] + ' ' + data['o_t_be'], format='%Y%m%d %H:%M:%S') + pd.to_timedelta(data['o_m_be'], unit='us')

# Handle missing values for 'o_d_mo' and 'o_t_mo'
missing_mask = data['o_d_mo'].isnull() | data['o_t_mo'].isnull()
data.loc[missing_mask, 'o_dtm_mo'] = np.nan

# Convert 'o_d_mo' and 'o_t_mo' to string and handle missing values
data['o_d_mo'] = data['o_d_mo'].fillna('').astype(str)
data['o_t_mo'] = data['o_t_mo'].fillna('').astype(str)

# Convert 'o_d_mo' and 'o_t_mo' to datetime
data.loc[~missing_mask, 'o_dtm_mo'] = pd.to_datetime(data['o_d_mo'] + ' ' + data['o_t_mo'], format='%Y%m%d %H:%M:%S') + pd.to_timedelta(data['o_m_mo'], unit='us')

选项 2:使用 np.where

import pandas as pd
import numpy as np

# Convert 'o_d_be' and 'o_t_be' to string
data['o_d_be'] = data['o_d_be'].astype(str)
data['o_t_be'] = data['o_t_be'].astype(str)

# Convert 'o_d_be' and 'o_t_be' to datetime
data['o_dtm_be'] = pd.to_datetime(data['o_d_be'] + ' ' + data['o_t_be'], format='%Y%m%d %H:%M:%S') + pd.to_timedelta(data['o_m_be'], unit='us')

# Convert 'o_d_mo' and 'o_t_mo' to string and handle missing values
data['o_d_mo'] = data['o_d_mo'].fillna('').astype(str)
data['o_t_mo'] = data['o_t_mo'].fillna('').astype(str)

# Convert 'o_d_mo' and 'o_t_mo' to datetime and handle missing values
data['o_dtm_mo'] = np.where(
    (data['o_d_mo'] == '') | (data['o_t_mo'] == ''),
    np.nan,
    pd.to_datetime(data['o_d_mo'] + ' ' + data['o_t_mo'], format='%Y%m%d %H:%M:%S') + pd.to_timedelta(data['o_m_mo'], unit='us')
)

0
投票

好吧,我成功改正了我的愚蠢错误。正如我之前解释的,数据库中的日期(年、月、日)最初是一个 int。我之前的代码(正下方)不适用于具有空值的列,因为 int 类型的日期已更改为 float。这是错误的。

data['o_d_be'] = data['o_d_be'].apply(lambda x: str(x))
data['o_t_be'] = data['o_t_be'].apply(lambda x: str(x))
data['o_dtm_be'] = pd.to_datetime(data['o_d_be'] + ' ' + data['o_t_be'], format='%Y%m%d %H:%M:%S') + pd.to_timedelta(data['o_m_be'], unit='us')

只需将浮点数转换回 int 即可使您建议的代码起作用。

na_mask = data['o_d_mo'].isnull()
data.loc[~na_mask, 'o_d_mo'] = data.loc[~na_mask, 'o_d_mo'].astype(int).astype(str)
data.loc[~na_mask, 'o_d_mo'] = data.loc[~na_mask, 'o_d_mo'].astype(str)
data.loc[~na_mask, 'o_d_mo'] = pd.to_datetime(data['o_d_mo'] + ' ' + data['o_d_mo'], format='%Y%m%d %H:%M:%S') + pd.to_timedelta(data['o_d_mo'], unit='us')

感谢您的帮助!

© www.soinside.com 2019 - 2024. All rights reserved.