Pandas中时间戳列表的反序列化

0 投票
2 回答
54 浏览
提问于 2025-04-14 16:54

我有一个数据表,里面有一列时间戳(Timestamp)。我用 to_csv 函数把它保存成了一个文件,现在想用 read_csv 函数把它读回来。但是我读出来的只有一列字符串,像这样:

df = pd.DataFrame({'col':["[]", "[Timestamp('2018-04-24 00:00:00'), Timestamp('2018-05-14 00:00:00'), Timestamp('2018-05-14 00:00:00')]"]})

我尝试用 str.extractall(r"Timestamp('\d-\d-\d 00:00:00)") 把这一列转换成时间戳列表,然后用 map(lambda lst : [pd.to_datetime(y) for y in lst] 来处理。

不过现在 extractall 这个函数没有起作用。

你能帮帮我吗?谢谢!

2 个回答

0

这是解决我问题的代码:

df['x'] = df['x'].str.extractall(r"Timestamp\('(\d+-\d+-\d+) 00:00:00'\)") \
                                                        .apply(pd.to_datetime, axis=1) \
                                                        .groupby(level=0)[0].apply(list)

为了优化计算时间,你可以在所有序列上直接使用 pd.to_datetime,而不是用 apply。

1

因为你有时间戳列表的字符串表示,所以可以结合使用 str.extractallto_datetimegroupby.agg 来处理这些数据。

df['out'] = (pd.to_datetime(df['col'].str.extractall(r"Timestamp\('(\d+-\d+-\d+ 00:00:00)'\)")[0])
               .groupby(level=0).agg(list).reindex(df.index, fill_value=[])
            )

输出结果:

                                                                                                      col                                                              out
0                                                                                                      []                                                               []
1  [Timestamp('2018-04-24 00:00:00'), Timestamp('2018-05-14 00:00:00'), Timestamp('2018-05-14 00:00:00')]  [2018-04-24 00:00:00, 2018-05-14 00:00:00, 2018-05-14 00:00:00]

原始回答

你遇到了一些问题,你的正则表达式不正确(括号没有转义、缺少捕获组、在 \d 后面缺少 + 等等)。另外,使用 to_datetime 将数据转换回日期时间格式:

df = pd.DataFrame({'timestamp': ["Timestamp('2018-04-24 00:00:00')",
                                 "Timestamp('2018-05-14 00:00:00')",
                                 "Timestamp('2018-05-14 00:00:00')"]
                  })

df['out'] = pd.to_datetime(df['timestamp'].str.extract(r"Timestamp\('(\d+-\d+-\d+ 00:00:00)'\)", expand=False))

你可以把正则表达式简化为 r"Timestamp\('([^)']+)'\)",因为序列化格式应该是有效的。

另一种方法是指定 %Y-%m-%d 格式在 to_datetime 中,并设置 exact=False,让 pandas 自动找到日期:

df['out'] = pd.to_datetime(df['timestamp'], format='%Y-%m-%d', exact=False)

输出结果:

                          timestamp        out
0  Timestamp('2018-04-24 00:00:00') 2018-04-24
1  Timestamp('2018-05-14 00:00:00') 2018-05-14
2  Timestamp('2018-05-14 00:00:00') 2018-05-14

如果你有时间戳的列表作为项目,逻辑大致是一样的。

举个例子:

df = pd.DataFrame({'timestamp': [["Timestamp('2018-04-24 00:00:00')",
                                  "Timestamp('2018-05-14 00:00:00')",
                                  "Timestamp('2018-05-14 00:00:00')"]]
                  })

def to_dt(lst):
    return pd.to_datetime(lst, format='%Y-%m-%d', exact=False).tolist()

df['out'] = df['timestamp'].apply(to_dt)

输出结果:

                                           timestamp                                                out
0  [Timestamp('2018-04-24 00:00:00'), Timestamp('...  [2018-04-24 00:00:00, 2018-05-14 00:00:00, 201...

撰写回答