Python, улучшающий производительность цикла - PullRequest
0 голосов
/ 29 мая 2018

Я создал класс под названием localSun.Я взял упрощенную модель системы Земля-Солнце и попытался вычислить высотный угол Солнца для любого места на Земле в любое время.Когда я запускаю код для текущего времени и проверяю время и добавить, он хорошо совпадает.Так что это работает.

Но тогда я хотел в основном пройти через один год и сохранить все углы высоты в массиве (массив Numpy) для определенного местоположения, и я пошел с интервалами в 1 минуту.

Вот моя самая первая наивная попытка, которая, я уверен, не подходит для производительности.В любом случае, я просто хотел проверить производительность.

import numpy as np
from datetime import datetime
from datetime import date
from datetime import timedelta
...

...  
altitudes = np.zeros(int(year/60))

m = datetime(2018, 5, 29, 15, 21, 0)
for i in range(0, len(altitudes)):
    n = m + timedelta(minutes = i+1)
    nn = localSun(30, 0, n)

    altitudes[i] = nn.altitude() # .altitude() is a method in localSun

высоты - это массив, в котором я хочу сохранить все высоты, и его размер равен 525969, что в основном равно количеству минут в году.

Объект localSun () принимает 3 параметра: colatitude (30 град.), Долготу (0 град.) И объект datetime, который имеет время чуть более часа назад (когда это опубликовано)

Итак, вопрос в том, что было бы хорошим эффективным способом прохождения года с интервалом в 1 минуту и ​​вычисления угла высоты в это время, потому что это кажется довольно медленным.Должен ли я использовать карту для обновления значений угла высоты вместо цикла for.Я предполагаю, что мне придется каждый раз создавать новый объект localSun тоже.Также, вероятно, плохо просто создавать эти переменные n и nn все время.

Мы можем предположить, что для объектов localSun все методы работают нормально.Я просто спрашиваю, как эффективно (если есть) пройти год с интервалом в 1 минуту и ​​обновить массив с высотой.Код, который у меня есть, должен раскрыть достаточно информации.

Возможно, я бы хотел сделать это всего через 1 секунду, поэтому было бы здорово узнать, есть ли эффективный способ.Я попробовал это, но это займет очень много времени, если я использую этот код.

Этот фрагмент кода занял около минуты на университетском компьютере, который, насколько я знаю, довольно быстрый.

Очень ценен, если кто-то может ответить.Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 29 мая 2018

Numpy имеет наивную datetime и timedelta поддержку , поэтому вы можете использовать такой подход:

start = datetime.datetime(2018,5,29,15,21,0)
end = datetime.datetime(2019,5,29,15,21,0)
n = np.arange(start, end, dtype='datetime64[m]') # [m] specifies the interval as minutes
altitudes = np.vectorize(lambda x, y, z: localSun(x, y, z).altitude())(30,0,n)

np.vectorize не быстровообще, но работает до тех пор, пока вы не сможете изменить 'localSun' для работы с массивами datetime.

0 голосов
/ 29 мая 2018

Поскольку вы уже используете numpy, вы можете сделать еще один шаг, набрав pandas.Он имеет мощные процедуры манипуляции с датой и временем, такие как pd.date_range:

import pandas as pd


start = pd.Timestamp(year=2018, month=1, day=1)
stop = pd.Timestamp(year=2018, month=12, day=31)
dates = pd.date_range(start, stop, freq='min')
altitudes = localSun(30, 0, dates)

Затем вам необходимо адаптировать localSun для работы с массивом pd.Timestamp, а не один datetime.datetime.

Переключение с минут на секунды будет таким же простым, как и с freq='min' на freq='S'.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...