首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >改进Skyfield中日出/日落计算的性能

改进Skyfield中日出/日落计算的性能
EN

Stack Overflow用户
提问于 2021-10-12 12:35:30
回答 1查看 50关注 0票数 0

给定坐标(经度/经度)和时间戳,我使用skyfield库为每个坐标/时间戳对计算太阳是否在该位置和时间升起:

代码语言:javascript
复制
import datetime as dt

import numpy as np
from skyfield import almanac
from skyfield.api import Loader
from skyfield.toposlib import wgs84
from skyfield_data import get_skyfield_data_path


load = Loader(get_skyfield_data_path())
eph = load("de421.bsp")
ts = load.timescale()

# Made up times
datetimes = [
    dt.datetime(2000, 1, 1, tzinfo=dt.timezone.utc)
    + dt.timedelta(minutes=m) for m in range(24 * 60)
]
times = ts.from_datetimes(datetimes)

# Made up coordinates
coordinates = np.array([
    (50.0, lon)
    for lon in np.linspace(0.0, 30.0, 1000)
])

results = []
for lat, lon in coordinates:
    pos = wgs84.latlon(lat, lon)
    is_day = almanac.sunrise_sunset(eph, pos)
    results.append(is_day(times))

这段代码可以工作,但速度太慢,不能满足我的需求。有没有办法将Python循环通过坐标移动到NumPy中?Skyfield文档说Skyfield使用NumPy,但据我所知,wgs84.latlon不接受NumPy数组作为输入。

如果无法避免Python循环,那么有没有一种方法可以提高速度呢?

请注意,在我的实际用例中,时间戳和坐标都是用户提供的,并且事先是未知的,所以我不能假设它们有任何特定的结构。

EN

回答 1

Stack Overflow用户

发布于 2021-10-12 13:19:36

多处理是CPU密集型活动的常见解决方案:看起来就是这样。

由于酸洗错误,不能在多个进程之间共享eph。这意味着每个进程都必须调用load()。然而,这似乎是相对较快的。下面的代码在我的机器上运行大约3秒。这可能会也可能不会比你目前的经验更好,因为你的原始问题中没有提到执行的持续时间。

代码语言:javascript
复制
import time
import datetime as dt
import numpy as np
from skyfield import almanac
from skyfield.api import Loader
from skyfield.toposlib import wgs84
from skyfield_data import get_skyfield_data_path
from concurrent.futures import ProcessPoolExecutor


load = Loader(get_skyfield_data_path())

ts = load.timescale()

# Made up times
datetimes = [
    dt.datetime(2000, 1, 1, tzinfo=dt.timezone.utc)
    + dt.timedelta(minutes=m) for m in range(24 * 60)
]
times = ts.from_datetimes(datetimes)

# Made up coordinates
coordinates = np.array([
    (50.0, lon)
    for lon in np.linspace(0.0, 30.0, 1000)
])


def docalc(lat, lon):
    pos = wgs84.latlon(lat, lon)
    eph = load('de421.bsp')
    return almanac.sunrise_sunset(eph, pos)(times)


def main():
    results = []
    with ProcessPoolExecutor() as executor:
        futures = []
        for lat, lon in coordinates:
            futures.append(executor.submit(docalc, lat, lon))
        for future in futures:
            results.append(future.result())
    return results


if __name__ == '__main__':
    s = time.perf_counter()
    main()
    e = time.perf_counter()
    print(f'Duration = {e-s:.4f}s')
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69540664

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档