meteostat 1.7.5__py3-none-any.whl → 2.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. meteostat/__init__.py +32 -19
  2. meteostat/api/daily.py +76 -0
  3. meteostat/api/hourly.py +80 -0
  4. meteostat/api/interpolate.py +240 -0
  5. meteostat/api/inventory.py +59 -0
  6. meteostat/api/merge.py +103 -0
  7. meteostat/api/monthly.py +73 -0
  8. meteostat/api/normals.py +144 -0
  9. meteostat/api/point.py +30 -0
  10. meteostat/api/stations.py +234 -0
  11. meteostat/api/timeseries.py +334 -0
  12. meteostat/core/cache.py +212 -59
  13. meteostat/core/config.py +158 -0
  14. meteostat/core/data.py +199 -0
  15. meteostat/core/logger.py +9 -0
  16. meteostat/core/network.py +82 -0
  17. meteostat/core/parameters.py +112 -0
  18. meteostat/core/providers.py +184 -0
  19. meteostat/core/schema.py +170 -0
  20. meteostat/core/validator.py +38 -0
  21. meteostat/enumerations.py +149 -0
  22. meteostat/interpolation/idw.py +120 -0
  23. meteostat/interpolation/lapserate.py +91 -0
  24. meteostat/interpolation/nearest.py +31 -0
  25. meteostat/parameters.py +354 -0
  26. meteostat/providers/dwd/climat.py +166 -0
  27. meteostat/providers/dwd/daily.py +144 -0
  28. meteostat/providers/dwd/hourly.py +218 -0
  29. meteostat/providers/dwd/monthly.py +138 -0
  30. meteostat/providers/dwd/mosmix.py +351 -0
  31. meteostat/providers/dwd/poi.py +117 -0
  32. meteostat/providers/dwd/shared.py +155 -0
  33. meteostat/providers/eccc/daily.py +87 -0
  34. meteostat/providers/eccc/hourly.py +104 -0
  35. meteostat/providers/eccc/monthly.py +66 -0
  36. meteostat/providers/eccc/shared.py +45 -0
  37. meteostat/providers/index.py +496 -0
  38. meteostat/providers/meteostat/daily.py +65 -0
  39. meteostat/providers/meteostat/daily_derived.py +110 -0
  40. meteostat/providers/meteostat/hourly.py +66 -0
  41. meteostat/providers/meteostat/monthly.py +45 -0
  42. meteostat/providers/meteostat/monthly_derived.py +106 -0
  43. meteostat/providers/meteostat/shared.py +93 -0
  44. meteostat/providers/metno/forecast.py +186 -0
  45. meteostat/providers/noaa/ghcnd.py +228 -0
  46. meteostat/providers/noaa/isd_lite.py +142 -0
  47. meteostat/providers/noaa/metar.py +163 -0
  48. meteostat/typing.py +113 -0
  49. meteostat/utils/conversions.py +231 -0
  50. meteostat/utils/data.py +194 -0
  51. meteostat/utils/geo.py +28 -0
  52. meteostat/utils/parsers.py +168 -0
  53. meteostat/utils/types.py +113 -0
  54. meteostat/utils/validators.py +31 -0
  55. meteostat-2.0.0.dist-info/METADATA +134 -0
  56. meteostat-2.0.0.dist-info/RECORD +63 -0
  57. {meteostat-1.7.5.dist-info → meteostat-2.0.0.dist-info}/WHEEL +1 -2
  58. meteostat/core/loader.py +0 -103
  59. meteostat/core/warn.py +0 -34
  60. meteostat/enumerations/granularity.py +0 -22
  61. meteostat/interface/base.py +0 -39
  62. meteostat/interface/daily.py +0 -118
  63. meteostat/interface/hourly.py +0 -154
  64. meteostat/interface/meteodata.py +0 -210
  65. meteostat/interface/monthly.py +0 -109
  66. meteostat/interface/normals.py +0 -245
  67. meteostat/interface/point.py +0 -143
  68. meteostat/interface/stations.py +0 -252
  69. meteostat/interface/timeseries.py +0 -237
  70. meteostat/series/aggregate.py +0 -48
  71. meteostat/series/convert.py +0 -28
  72. meteostat/series/count.py +0 -17
  73. meteostat/series/coverage.py +0 -20
  74. meteostat/series/fetch.py +0 -28
  75. meteostat/series/interpolate.py +0 -47
  76. meteostat/series/normalize.py +0 -76
  77. meteostat/series/stations.py +0 -22
  78. meteostat/units.py +0 -149
  79. meteostat/utilities/__init__.py +0 -0
  80. meteostat/utilities/aggregations.py +0 -37
  81. meteostat/utilities/endpoint.py +0 -33
  82. meteostat/utilities/helpers.py +0 -70
  83. meteostat/utilities/mutations.py +0 -85
  84. meteostat/utilities/validations.py +0 -30
  85. meteostat-1.7.5.dist-info/METADATA +0 -112
  86. meteostat-1.7.5.dist-info/RECORD +0 -39
  87. meteostat-1.7.5.dist-info/top_level.txt +0 -1
  88. /meteostat/{core → api}/__init__.py +0 -0
  89. /meteostat/{enumerations → interpolation}/__init__.py +0 -0
  90. /meteostat/{interface → providers}/__init__.py +0 -0
  91. /meteostat/{interface/interpolate.py → py.typed} +0 -0
  92. /meteostat/{series → utils}/__init__.py +0 -0
  93. {meteostat-1.7.5.dist-info → meteostat-2.0.0.dist-info/licenses}/LICENSE +0 -0
@@ -1,154 +0,0 @@
1
- """
2
- Hourly Class
3
-
4
- Meteorological data provided by Meteostat (https://dev.meteostat.net)
5
- under the terms of the Creative Commons Attribution-NonCommercial
6
- 4.0 International Public License.
7
-
8
- The code is licensed under the MIT license.
9
- """
10
-
11
- from math import floor
12
- from datetime import datetime, timedelta
13
- from typing import Optional, Union
14
- import pytz
15
- import pandas as pd
16
- from meteostat.enumerations.granularity import Granularity
17
- from meteostat.utilities.aggregations import degree_mean
18
- from meteostat.interface.timeseries import TimeSeries
19
- from meteostat.interface.point import Point
20
- from meteostat.utilities.mutations import calculate_dwpt
21
-
22
-
23
- class Hourly(TimeSeries):
24
- """
25
- Retrieve hourly weather observations for one or multiple weather stations or
26
- a single geographical point
27
- """
28
-
29
- # The cache subdirectory
30
- cache_subdir = "hourly"
31
-
32
- # Granularity
33
- granularity = Granularity.HOURLY
34
-
35
- # Download data as annual chunks
36
- # This cannot be changed and is only kept for backward compatibility
37
- chunked = True
38
-
39
- # The time zone
40
- _timezone: Optional[str] = None
41
-
42
- # Default frequency
43
- _freq = "1h"
44
-
45
- # Source mappings
46
- _source_mappings = {
47
- "metar": "D",
48
- "model": "E",
49
- "isd_lite": "B",
50
- "synop": "C",
51
- "dwd_poi": "C",
52
- "dwd_hourly": "A",
53
- "dwd_mosmix": "E",
54
- "metno_forecast": "E",
55
- "eccc_hourly": "A",
56
- }
57
-
58
- # Flag which represents model data
59
- _model_flag = "E"
60
-
61
- # Raw data columns
62
- _columns = [
63
- "year",
64
- "month",
65
- "day",
66
- "hour",
67
- "temp",
68
- {"dwpt": calculate_dwpt},
69
- "rhum",
70
- "prcp",
71
- {"snow": "snwd"},
72
- "wdir",
73
- "wspd",
74
- "wpgt",
75
- "pres",
76
- "tsun",
77
- "coco",
78
- ]
79
-
80
- # Index of first meteorological column
81
- _first_met_col = 4
82
-
83
- # Columns for date parsing
84
- _parse_dates = ["year", "month", "day", "hour"]
85
-
86
- # Default aggregation functions
87
- aggregations = {
88
- "temp": "mean",
89
- "dwpt": "mean",
90
- "rhum": "mean",
91
- "prcp": "sum",
92
- "snow": "max",
93
- "wdir": degree_mean,
94
- "wspd": "mean",
95
- "wpgt": "max",
96
- "pres": "mean",
97
- "tsun": "sum",
98
- "coco": "max",
99
- }
100
-
101
- def _set_time(
102
- self,
103
- start: Optional[datetime] = None,
104
- end: Optional[datetime] = None,
105
- timezone: Optional[str] = None,
106
- ) -> None:
107
- """
108
- Set & adapt the period's time zone
109
- """
110
- if timezone:
111
- # Save timezone
112
- self._timezone = timezone
113
-
114
- if start and end:
115
- # Initialize time zone
116
- timezone = pytz.timezone(self._timezone)
117
-
118
- # Set start date
119
- start = timezone.localize(start, is_dst=None).astimezone(pytz.utc)
120
-
121
- # Set end date
122
- end = timezone.localize(end, is_dst=None).astimezone(pytz.utc)
123
-
124
- if self.chunked:
125
- self._annual_steps = [
126
- start.year + i for i in range(end.year - start.year + 1)
127
- ]
128
-
129
- self._start = start
130
- self._end = end
131
-
132
- def __init__(
133
- self,
134
- loc: Union[pd.DataFrame, Point, list, str], # Station(s) or geo point
135
- start=datetime(1890, 1, 1, 0, 0, 0),
136
- end=datetime.combine(
137
- datetime.today().date() + timedelta(days=10), datetime.max.time()
138
- ),
139
- timezone: Optional[str] = None,
140
- model=True, # Include model data?
141
- flags=False, # Load source flags?
142
- ) -> None:
143
- # Set time zone and adapt period
144
- self._set_time(start, end, timezone)
145
-
146
- # Initialize time series
147
- self._init_time_series(loc, start, end, model, flags)
148
-
149
- def expected_rows(self) -> int:
150
- """
151
- Return the number of rows expected for the defined date range
152
- """
153
-
154
- return floor((self._end - self._start).total_seconds() / 3600) + 1
@@ -1,210 +0,0 @@
1
- """
2
- Meteorological Data Class
3
-
4
- A parent class for both time series and
5
- climate normals data
6
-
7
- Meteorological data provided by Meteostat (https://dev.meteostat.net)
8
- under the terms of the Creative Commons Attribution-NonCommercial
9
- 4.0 International Public License.
10
-
11
- The code is licensed under the MIT license.
12
- """
13
-
14
- from collections.abc import Callable
15
- from typing import Dict, List, Union
16
- import pandas as pd
17
- from meteostat.enumerations.granularity import Granularity
18
- from meteostat.core.loader import processing_handler
19
- from meteostat.utilities.mutations import adjust_temp
20
- from meteostat.utilities.aggregations import weighted_average
21
- from meteostat.interface.base import Base
22
-
23
-
24
- class MeteoData(Base):
25
- """
26
- A parent class for both time series and
27
- climate normals data
28
- """
29
-
30
- # The list of weather Stations
31
- _stations: Union[pd.Index, None] = None
32
-
33
- # The data frame
34
- _data: pd.DataFrame = pd.DataFrame()
35
-
36
- @property
37
- def _raw_columns(self) -> List[str]:
38
- """
39
- Get the list of raw data columns, excluding any dicts with callable values
40
- """
41
- return [
42
- list(col.values())[0] if isinstance(col, dict) else col
43
- for col in self._columns
44
- if not (
45
- isinstance(col, dict)
46
- and (
47
- isinstance(list(col.values())[0], Callable)
48
- or list(col.values())[0] is None
49
- )
50
- )
51
- ]
52
-
53
- @property
54
- def _processed_columns(self) -> List[str]:
55
- """
56
- Get the list of processed data columns, excluding any dicts with callable values
57
- """
58
- return [
59
- list(col.keys())[0] if isinstance(col, dict) else col
60
- for col in self._columns[self._first_met_col :]
61
- ]
62
-
63
- @property
64
- def _renamed_columns(self) -> Dict[str, str]:
65
- """
66
- Get the dict of renamed data columns, including `_source` suffixes
67
- """
68
- return {
69
- new_key: new_val
70
- for d in self._columns
71
- if isinstance(d, dict)
72
- for k, v in d.items()
73
- if not isinstance(v, Callable)
74
- for new_key, new_val in ((v, k), (f"{v}_source", f"{k}_source"))
75
- }
76
-
77
- @property
78
- def _virtual_columns(self) -> Dict[str, str]:
79
- """
80
- Get the dict of virtual data columns
81
- """
82
- return {
83
- k: v
84
- for d in self._columns
85
- if isinstance(d, dict)
86
- for k, v in d.items()
87
- if isinstance(v, Callable)
88
- }
89
-
90
- def _get_datasets(self) -> list:
91
- """
92
- Get list of datasets
93
- """
94
-
95
- if self.granularity in (Granularity.HOURLY, Granularity.DAILY):
96
- datasets = [
97
- (str(station), year)
98
- for station in self._stations
99
- for year in self._annual_steps
100
- ]
101
- else:
102
- datasets = [(str(station),) for station in self._stations]
103
-
104
- return datasets
105
-
106
- def _get_data(self) -> None:
107
- """
108
- Get all required data dumps
109
- """
110
-
111
- if len(self._stations) > 0:
112
- # Get list of datasets
113
- datasets = self._get_datasets()
114
-
115
- # Data Processings
116
- return processing_handler(
117
- datasets, self._load_data, self.processes, self.threads
118
- )
119
-
120
- # Empty DataFrame
121
- return pd.DataFrame(columns=self._processed_columns)
122
-
123
- # pylint: disable=too-many-branches
124
- def _resolve_point(
125
- self, method: str, stations: pd.DataFrame, alt: int, adapt_temp: bool
126
- ) -> None:
127
- """
128
- Project weather station data onto a single point
129
- """
130
-
131
- if self._stations.size == 0 or self._data.size == 0:
132
- return
133
-
134
- if method == "nearest":
135
- if adapt_temp:
136
- # Join elevation of involved weather stations
137
- data = self._data.join(stations["elevation"], on="station")
138
-
139
- # Adapt temperature-like data based on altitude
140
- data = adjust_temp(data, alt)
141
-
142
- # Drop elevation & round
143
- data = data.drop("elevation", axis=1).round(1)
144
-
145
- else:
146
- data = self._data
147
-
148
- if self.granularity == Granularity.NORMALS:
149
- self._data = data.groupby(level=["start", "end", "month"]).agg("first")
150
-
151
- else:
152
- self._data = data.groupby(
153
- pd.Grouper(level="time", freq=self._freq)
154
- ).agg("first")
155
-
156
- else:
157
- # Join score and elevation of involved weather stations
158
- data = self._data.join(stations[["score", "elevation"]], on="station")
159
-
160
- # Adapt temperature-like data based on altitude
161
- if adapt_temp:
162
- data = adjust_temp(data, alt)
163
-
164
- # Exclude non-mean data & perform aggregation
165
- if not self.granularity == Granularity.NORMALS:
166
- excluded = data["wdir"]
167
- excluded = excluded.groupby(
168
- pd.Grouper(level="time", freq=self._freq)
169
- ).agg("first")
170
-
171
- # Aggregate mean data
172
- if self.granularity == Granularity.NORMALS:
173
- data = data.groupby(level=["start", "end", "month"]).apply(
174
- weighted_average
175
- )
176
-
177
- # Remove obsolete index column
178
- try:
179
- data = data.reset_index(level=3, drop=True)
180
- except IndexError:
181
- pass
182
-
183
- else:
184
- data = data.groupby(pd.Grouper(level="time", freq=self._freq)).apply(
185
- weighted_average
186
- )
187
-
188
- # Drop RangeIndex
189
- data.index = data.index.droplevel(1)
190
-
191
- # Merge excluded fields
192
- data["wdir"] = excluded
193
-
194
- # Drop score and elevation
195
- self._data = data.drop(["score", "elevation"], axis=1).round(1)
196
-
197
- # Set placeholder station ID
198
- self._data["station"] = "XXXXX"
199
-
200
- # Set index
201
- if self.granularity == Granularity.NORMALS:
202
- self._data = self._data.set_index("station", append=True)
203
- self._data = self._data.reorder_levels(["station", "start", "end", "month"])
204
- else:
205
- self._data = self._data.set_index(
206
- ["station", self._data.index.get_level_values("time")]
207
- )
208
-
209
- # Set station index
210
- self._stations = pd.Index(["XXXXX"])
@@ -1,109 +0,0 @@
1
- """
2
- Monthly Class
3
-
4
- Meteorological data provided by Meteostat (https://dev.meteostat.net)
5
- under the terms of the Creative Commons Attribution-NonCommercial
6
- 4.0 International Public License.
7
-
8
- The code is licensed under the MIT license.
9
- """
10
-
11
- from datetime import datetime
12
- from typing import Union
13
- import pandas as pd
14
- from meteostat.enumerations.granularity import Granularity
15
- from meteostat.interface.timeseries import TimeSeries
16
- from meteostat.interface.point import Point
17
-
18
-
19
- class Monthly(TimeSeries):
20
- """
21
- Retrieve monthly weather data for one or multiple weather stations or
22
- a single geographical point
23
- """
24
-
25
- # The cache subdirectory
26
- cache_subdir = "monthly"
27
-
28
- # Granularity
29
- granularity = Granularity.MONTHLY
30
-
31
- # Default frequency
32
- _freq = "1MS"
33
-
34
- # Source mappings
35
- _source_mappings = {
36
- "dwd_monthly": "A",
37
- "eccc_monthly": "A",
38
- "dwd_daily": "C",
39
- "eccc_daily": "C",
40
- "ghcnd": "D",
41
- "dwd_hourly": "E",
42
- "eccc_hourly": "E",
43
- "isd_lite": "F",
44
- "synop": "G",
45
- "dwd_poi": "G",
46
- "metar": "H",
47
- "model": "I",
48
- "dwd_mosmix": "I",
49
- "metno_forecast": "I",
50
- }
51
-
52
- # Flag which represents model data
53
- _model_flag = "I"
54
-
55
- # Columns
56
- _columns = [
57
- "year",
58
- "month",
59
- {"tavg": "temp"},
60
- "tmin",
61
- "tmax",
62
- "prcp",
63
- "wspd",
64
- "pres",
65
- "tsun",
66
- ]
67
-
68
- # Index of first meteorological column
69
- _first_met_col = 2
70
-
71
- # Columns for date parsing
72
- _parse_dates = ["year", "month"]
73
-
74
- # Default aggregation functions
75
- aggregations = {
76
- "tavg": "mean",
77
- "tmin": "mean",
78
- "tmax": "mean",
79
- "prcp": "sum",
80
- "wspd": "mean",
81
- "pres": "mean",
82
- "tsun": "sum",
83
- }
84
-
85
- def __init__(
86
- self,
87
- loc: Union[pd.DataFrame, Point, list, str], # Station(s) or geo point
88
- start: datetime = None,
89
- end: datetime = None,
90
- model: bool = True, # Include model data?
91
- flags: bool = False, # Load source flags?
92
- ) -> None:
93
- # Set start date
94
- if start is not None:
95
- start = start.replace(day=1)
96
-
97
- # Initialize time series
98
- self._init_time_series(loc, start, end, model, flags)
99
-
100
- def expected_rows(self) -> int:
101
- """
102
- Return the number of rows expected for the defined date range
103
- """
104
-
105
- return (
106
- (self._end.year - self._start.year) * 12
107
- + self._end.month
108
- - self._start.month
109
- ) + 1