python 转换极坐标中的字符串时如何处理夏季和冬季的时间戳

zbsbpyhn  于 2023-02-11  发布在  Python
关注(0)|答案(2)|浏览(127)

我试图将字符串时间戳从相机放入RAW文件元数据的时间戳转换为polars datetime,但当我同时拥有夏令时和冬令时的时间戳时,polars抛出了这个错误。

ComputeError: Different timezones found during 'strptime' operation.

我如何说服它成功地转换这些?(理想情况下处理不同的时区以及从夏季到冬季的时间变化)
然后,如何将这些时间戳转换回正确的本地时钟时间以供显示?
请注意,虽然时间戳字符串只显示偏移量,但元数据中有一个exif字段“TimeZoneCity”,以及仅包含本地(原始)时间戳的字段

import polars as plr

testdata=[
    {'name': 'BST 11:06', 'ts': '2022:06:27 11:06:12.16+01:00'},
    {'name': 'GMT 7:06', 'ts': '2022:12:27 12:06:12.16+00:00'},
]

pdf = plr.DataFrame(testdata)
pdfts = pdf.with_column(plr.col('ts').str.strptime(plr.Datetime, fmt = "%Y:%m:%d %H:%M:%S.%f%z"))

print(pdf)
print(pdfts)

看起来我需要使用tz_convert,但是我看不出如何将其添加到转换表达式中,也看不出相关文档页中有什么内容,只是404到dt_namespace的链接断开了

ccrfmcuu

ccrfmcuu1#

极坐标0.16更新

由于PR 6496已合并,您可以将混合偏移解析为UTC,然后设置时区:

import polars as pl

pdf = pl.DataFrame([
    {'name': 'BST 11:06', 'ts': '2022:06:27 11:06:12.16+01:00'},
    {'name': 'GMT 7:06', 'ts': '2022:12:27 12:06:12.16+00:00'},
])

pdfts = pdf.with_columns(
    pl.col('ts').str.strptime(
        pl.Datetime(time_unit="us"), fmt="%Y:%m:%d %H:%M:%S.%f%z", utc=True)
    .dt.convert_time_zone("Europe/London")
)

print(pdfts)
shape: (2, 2)
┌───────────┬─────────────────────────────┐
│ name      ┆ ts                          │
│ ---       ┆ ---                         │
│ str       ┆ datetime[μs, Europe/London] │
╞═══════════╪═════════════════════════════╡
│ BST 11:06 ┆ 2022-06-27 11:06:12 BST     │
│ GMT 7:06  ┆ 2022-12-27 12:06:12 GMT     │
└───────────┴─────────────────────────────┘
旧版本:

以下是您可以使用的解决方法:删除UTC偏移量并本地化到预定义的时区。**注意:**仅当UTC偏移量和时区一致时,结果才正确。

timezone = "Europe/London"

pdfts = pdf.with_column(
    plr.col('ts')
    .str.replace("[+|-][0-9]{2}:[0-9]{2}", "")
    .str.strptime(plr.Datetime, fmt="%Y:%m:%d %H:%M:%S%.f")
    .dt.tz_localize(timezone)
)

print(pdf)
┌───────────┬──────────────────────────────┐
│ name      ┆ ts                           │
│ ---       ┆ ---                          │
│ str       ┆ str                          │
╞═══════════╪══════════════════════════════╡
│ BST 11:06 ┆ 2022:06:27 11:06:12.16+01:00 │
├╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ GMT 7:06  ┆ 2022:12:27 12:06:12.16+00:00 │
└───────────┴──────────────────────────────┘
print(pdfts)
┌───────────┬─────────────────────────────┐
│ name      ┆ ts                          │
│ ---       ┆ ---                         │
│ str       ┆ datetime[ns, Europe/London] │
╞═══════════╪═════════════════════════════╡
│ BST 11:06 ┆ 2022-06-27 11:06:12.160 BST │
├╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ GMT 7:06  ┆ 2022-12-27 12:06:12.160 GMT │
└───────────┴─────────────────────────────┘

旁注:公平地说,pandas也不处理混合的UTC偏移量,除非你直接解析为UTC(pd.to_datetime中的关键字utc=True)。对于混合的UTC偏移量,它只能使用一系列原生Python datetime对象。这使得panda的很多时间序列功能,比如dt访问器不可用。

y1aodyip

y1aodyip2#

类似于FObersteiner的解决方案,但这将手动解析偏移,而不是假设您的相机的偏移与预定义的时区定义正确匹配。
第一步是使用extract正则表达式将偏移量与其余时间分开。偏移量被拆分为小时和分钟(包括符号)。然后我们将第一步中的日期时间组件作为原始时间进行strptime,加上/减去偏移量,将其本地化为UTC。然后将其设置为所需的时区(在本例中为欧洲/伦敦)。**(我加载polars作为pl,而不是plr,因此根据需要进行调整)

(pdf 
.with_columns(
    [pl.col('ts').str.extract("(\d{4}:\d{2}:\d{2} \d{2}:\d{2}:\d{2}\.\d{2})"),
     pl.col('ts').str.extract("\d{4}:\d{2}:\d{2} \d{2}:\d{2}:\d{2}\.\d{2}((\+|-)\d{2}):\d{2}")
                 .cast(pl.Float64()).alias("offset"),
     pl.col('ts').str.extract("\d{4}:\d{2}:\d{2} \d{2}:\d{2}:\d{2}\.\d{2}(\+|-)\d{2}:(\d{2})", group_index=2)
                 .cast(pl.Float64()).alias("offset_minute")])
.select(
    ['name', 
     (pl.col('ts').str.strptime(pl.Datetime(), "%Y:%m:%d %H:%M:%S%.f") - pl.duration(hours=pl.col('offset'), minutes=pl.col('offset_minute')))
                  .dt.tz_localize('UTC').dt.with_time_zone('Europe/London')]))



shape: (2, 3)
┌───────────┬────────┬─────────────────────────────┐
│ name      ┆ offset ┆ dt                          │
│ ---       ┆ ---    ┆ ---                         │
│ str       ┆ f64    ┆ datetime[ns, Europe/London] │
╞═══════════╪════════╪═════════════════════════════╡
│ BST 11:06 ┆ 1.0    ┆ 2022-06-27 11:06:12.160 BST │
│ GMT 7:06  ┆ 0.0    ┆ 2022-12-27 12:06:12.160 GMT │
└───────────┴────────┴─────────────────────────────┘

相关问题