如何将带有开始和结束的结构列时间戳转换为普通的 pythonic 戳列?

How can convert struct column timestamp with start and end into normal pythonic stamp column?

我有一个时间序列数据透视表 table,其结构时间戳列包括 startend 记录的时间范围,如下所示:

import pandas as pd
pd.set_option('max_colwidth', 400)
df = pd.DataFrame({'timestamp': ['{"start":"2022-01-19T00:00:00.000+0000","end":"2022-01-20T00:00:00.000+0000"}'],
                   "X1": [25],
                   "X2": [33],
                   })
df 
#                                                                       timestamp   X1  X2
#0  {"start":"2022-01-19T00:00:00.000+0000","end":"2022-01-20T00:00:00.000+0000"}   25  33

由于后面我会使用时间戳作为时间序列分析的指标,需要将其转化为时间戳,只需end/start。 我曾尝试使用正则表达式找到解决方案,但可能会基于此 失败,如下所示:

df[["start_timestamp", "end_timestamp"]] = (
    df["timestamp"].str.extractall(r"(\d+\.\d+\.\d+)").unstack().ffill(axis=1)
)

但我得到:

ValueError: Columns must be same length as key

所以我尝试达到以下预期数据帧:

df = pd.DataFrame({'timestamp': ['{"start":"2022-01-19T00:00:00.000+0000","end":"2022-01-20T00:00:00.000+0000"}'],
                   'start_timestamp': ['2022-01-19T00:00:00.000+0000'],
                   'end_timestamp': ['2022-01-20T00:00:00.000+0000'],
                   "X1": [25],
                   "X2": [33]})
df 
#                                                                       timestamp   start_timestamp                 end_timestamp                   X1  X2
#0  {"start":"2022-01-19T00:00:00.000+0000","end":"2022-01-20T00:00:00.000+0000"}   2022-01-19T00:00:00.000+0000    2022-01-20T00:00:00.000+0000    25  33

您可以使用 extract 调用提取这两个值:

df[["start_timestamp", "end_timestamp"]] = df["timestamp"].str.extract(r'"start":"([^"]*)","end":"([^"]+)')

"start":"([^"]*)","end":"([^"]+) 正则表达式匹配 "start":",然后将 " 以外的任何零个或多个字符捕获到第 1 组(start 列值),然后匹配 ","end":" 然后将 " 以外的一个或多个字符捕获到第 2 组(end 列值)。

此外,如果您拥有的数据有效 JSON,您可以解析 JSON 而不是使用正则表达式:

def extract_startend(x):
    j = json.loads(x)
    return pd.Series([j["start"], j["end"]])

df[["start_timestamp", "end_timestamp"]] = df["timestamp"].apply(extract_startend)

print(df.to_string()) 的输出:

                                                                   timestamp  X1  X2               start_timestamp                 end_timestamp
0  {"start":"2022-01-19T00:00:00.000+0000","end":"2022-01-20T00:00:.........  25  33  2022-01-19T00:00:00.000+0000  2022-01-20T00:00:00.000+0000

这可能不是最有效的方法,但它有效:

df[['start_timestamp','end_timestamp']]=df['timestamp'].str.split(',',expand=True)
df['start_timestamp']=df['start_timestamp'].str.extract('(\d{4}\-\d{2}\-\d{2}T\d{2}\:\d{2}\:\d{2}\.\d{3}\+\d{4})')
df['end_timestamp']=df['end_timestamp'].str.extract('(\d{4}\-\d{2}\-\d{2}T\d{2}\:\d{2}\:\d{2}\.\d{3}\+\d{4})')