如何将带有开始和结束的结构列时间戳转换为普通的 pythonic 戳列?
How can convert struct column timestamp with start and end into normal pythonic stamp column?
我有一个时间序列数据透视表 table,其结构时间戳列包括 start
和 end
记录的时间范围,如下所示:
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})')
我有一个时间序列数据透视表 table,其结构时间戳列包括 start
和 end
记录的时间范围,如下所示:
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})')