'Iterate trough a converted datetime pandas dataframe with a external function
https://rhodesmill.org/skyfield/positions.html#azimuth-and-altitude-from-a-geographic-position
Hi I have function that generates a sun-shot azimuth on a specific date and time on a specific place, using the package skyfield for astronomical calculations.
What do I want:
iterate trough the
df2.cdtrows as fix time, currentlyastro = Nieuwe_diep.at(ts.utc(2019, 12, 31, 8, 41, 44)).observe(sun)for fix#1add a new column to
df2, called:df2.azimuthcontaining the output ofaztrough row itteration.
Currently I can only generate the azimuth for the first fix, with this code:
# Sunshot Azimuth - hour angle method
from skyfield.api import N,S,E,W, wgs84
from skyfield.api import load
import pandas as pd
# location Port of Den Helder, Nieuwe diep:
lat = 52+(57/60)+(26.9/3600)
lon = 4+(46/60)+(37.5/3600)
# fix1 @ 2019-12-31 08:41:44 UTC
ts = load.timescale()
t = ts.utc(2019, 12, 31)
planets = load('de421.bsp')
earth, sun = planets['earth'], planets['sun']
# Altitude and azimuth in the sky for a specific geographic location
earth = planets['earth']
Nieuwe_diep = earth + wgs84.latlon(lat * N, lon * E, elevation_m=6)
astro = Nieuwe_diep.at(ts.utc(2019, 12, 31, 8, 41, 44)).observe(sun)
app = astro.apparent()
alt, az, distance = app.altaz()
print('alt: ' + alt.dstr())
print('az: ' + az.dstr())
print(distance)
print('lat, lon: ' + str(lat), str(lon))
#dt_utc = df2['datetime_UTC']
print('az: {:.3f}'.format(az.degrees)) # desired output for azimuth in decimal degrees
print('az: '+ az.dstr(format=u'{0}{1}°{2:02}′{3:02}.{4:0{5}}″'))
which results in:
alt: 04deg 18' 42.2"
az: 138deg 52' 22.3"
0.983305 au
lat, lon: 52.95747222222222 4.777083333333334
az: 138.873
az: 138°52′22.3″
I have a pandas dataframe that consists of times of when I want to know the suns Azimuth. The column cdt
# cdt: converted datetime
df2['cdt'] = df2['datetime_UTC'].dt.strftime('%Y, %m, %d, %H, %M, %S')
print(df2)
cdt = df2.cdt
date time datetime_UTC cdt
0 2019-12-31 08:41:44 2019-12-31 08:41:44 2019, 12, 31, 08, 41, 44
1 2019-12-31 08:43:16 2019-12-31 08:43:16 2019, 12, 31, 08, 43, 16
2 2019-12-31 08:44:12 2019-12-31 08:44:12 2019, 12, 31, 08, 44, 12
3 2019-12-31 08:44:52 2019-12-31 08:44:52 2019, 12, 31, 08, 44, 52
4 2019-12-31 08:46:01 2019-12-31 08:46:01 2019, 12, 31, 08, 46, 01
5 2019-12-31 08:46:42 2019-12-31 08:46:42 2019, 12, 31, 08, 46, 42
6 2019-12-31 08:47:21 2019-12-31 08:47:21 2019, 12, 31, 08, 47, 21
7 2019-12-31 08:48:12 2019-12-31 08:48:12 2019, 12, 31, 08, 48, 12
8 2019-12-31 08:48:58 2019-12-31 08:48:58 2019, 12, 31, 08, 48, 58
9 2019-12-31 09:07:08 2019-12-31 09:07:08 2019, 12, 31, 09, 07, 08
10 2019-12-31 09:07:24 2019-12-31 09:07:24 2019, 12, 31, 09, 07, 24
11 2019-12-31 09:07:45 2019-12-31 09:07:45 2019, 12, 31, 09, 07, 45
12 2019-12-31 09:08:03 2019-12-31 09:08:03 2019, 12, 31, 09, 08, 03
13 2019-12-31 09:08:19 2019-12-31 09:08:19 2019, 12, 31, 09, 08, 19
14 2019-12-31 09:08:34 2019-12-31 09:08:34 2019, 12, 31, 09, 08, 34
15 2019-12-31 09:08:50 2019-12-31 09:08:50 2019, 12, 31, 09, 08, 50
16 2019-12-31 09:09:13 2019-12-31 09:09:13 2019, 12, 31, 09, 09, 13
17 2019-12-31 09:09:33 2019-12-31 09:09:33 2019, 12, 31, 09, 09, 33
18 2019-12-31 09:09:57 2019-12-31 09:09:57 2019, 12, 31, 09, 09, 57
19 2019-12-31 09:10:20 2019-12-31 09:10:20 2019, 12, 31, 09, 10, 20
Solution 1:[1]
I think this would work. You'd have to take the output and deal with that in a list, dictionary or some other dataframe. Also, there seems like there should be a better way to pass and parse the utc time but I'm not familiar with the library.
import io
data = '''date time datetime_UTC
2019-12-31 08:41:44 2019-12-31 08:41:44
2019-12-31 08:43:16 2019-12-31 08:43:16
2019-12-31 08:44:12 2019-12-31 08:44:12
'''
df2 = pd.read_csv(io.StringIO(data), sep=' \s+', engine='python')
df2['datetime_UTC'] = pd.to_datetime(df2['datetime_UTC'])
df2['cdt'] = df2['datetime_UTC'].dt.strftime('%Y,%m,%d,%H,%M,%S')
# note I changed the formatting to remove spaces for later parsing
def calc_az(tutc):
yr=int(tutc.split(',')[0])
mo=int(tutc.split(',')[1])
da=int(tutc.split(',')[2])
hr=int(tutc.split(',')[3])
mi=int(tutc.split(',')[4])
se=int(tutc.split(',')[5])
# location Port of Den Helder, Nieuwe diep:
lat = 52+(57/60)+(26.9/3600)
lon = 4+(46/60)+(37.5/3600)
# fix1 @ 2019-12-31 08:41:44 UTC
ts = load.timescale()
t = ts.utc(2019, 12, 31)
planets = load('de421.bsp')
earth, sun = planets['earth'], planets['sun']
# Altitude and azimuth in the sky for a specific geographic location
earth = planets['earth']
Nieuwe_diep = earth + wgs84.latlon(lat * N, lon * E, elevation_m=6)
# astro = Nieuwe_diep.at(ts.utc(2019, 12, 31, 8, 41, 44)).observe(sun)
astro = Nieuwe_diep.at(ts.utc(yr, mo, da, hr, mi, se)).observe(sun)
app = astro.apparent()
alt, az, distance = app.altaz()
print('alt: ' + alt.dstr())
print('az: ' + az.dstr())
print(distance)
print('lat, lon: ' + str(lat), str(lon))
#dt_utc = df2['datetime_UTC']
print('az: {:.3f}'.format(az.degrees)) # desired output for azimuth in decimal degrees
print('az: '+ az.dstr(format=u'{0}{1}°{2:02}?{3:02}.{4:0{5}}?'))
print('\n'*2)
return
df2['cdt'].apply(calc_az)
output
alt: 04deg 18' 42.2"
az: 138deg 52' 22.3"
0.983305 au
lat, lon: 52.95747222222222 4.777083333333334
az: 138.873
az: 138°52?22.3?
alt: 04deg 27' 47.3"
az: 139deg 11' 31.5"
0.983305 au
lat, lon: 52.95747222222222 4.777083333333334
az: 139.192
az: 139°11?31.5?
alt: 04deg 33' 17.4"
az: 139deg 23' 11.9"
0.983305 au
lat, lon: 52.95747222222222 4.777083333333334
az: 139.387
az: 139°23?11.9?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Jonathan Leon |
