oda-data 2.0.3__tar.gz → 2.0.5__tar.gz
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.
- {oda_data-2.0.3 → oda_data-2.0.5}/PKG-INFO +1 -1
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/indicators/research/policy_markers.py +5 -1
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/indicators/research/sector_imputations.py +6 -1
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/tools/cache.py +8 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/tools/names/create_mapping.py +32 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/pyproject.toml +1 -1
- {oda_data-2.0.3 → oda_data-2.0.5}/LICENSE +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/README.md +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/.raw_data/README.md +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/__init__.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/api/__init__.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/api/constants.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/api/oecd.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/api/representations.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/api/sources.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/clean_data/__init__.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/clean_data/channels.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/clean_data/common.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/clean_data/crs_channel_mapping.csv +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/clean_data/dtypes.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/clean_data/schema.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/clean_data/validation.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/config.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/indicators/__init__.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/indicators/common.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/indicators/crs/__init__.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/indicators/crs/common.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/indicators/crs/crs_functions.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/indicators/crs/crs_indicators.json +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/indicators/crs/oecd.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/indicators/crs/one.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/indicators/dac1/__init__.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/indicators/dac1/common.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/indicators/dac1/dac1_functions.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/indicators/dac1/dac1_indicators.json +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/indicators/dac1/oecd.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/indicators/dac1/one.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/indicators/dac2a/__init__.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/indicators/dac2a/common.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/indicators/dac2a/dac2a_functions.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/indicators/dac2a/dac2a_indicators.json +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/indicators/dac2a/oecd.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/indicators/dac2a/one.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/indicators/indicator.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/indicators/research/__init__.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/indicators/research/eu.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/logger.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/settings/crs_flow_types.json +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/settings/crs_modalities.json +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/settings/crs_policy_markers.json +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/settings/crs_purpose.json +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/settings/crs_type_of_finance.json +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/settings/dac1_aid_flow_types.json +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/settings/dac2a_aid_type.json +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/settings/flow_types.json +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/settings/indicators.json +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/settings/key_columns.json +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/settings/provider_groupings.json +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/settings/recipient_groupings.json +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/settings/v1_indicators_mapping.json +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/tools/__init__.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/tools/compatibility.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/tools/gni.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/tools/groupings.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/tools/names/__init__.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/tools/names/add.py +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/tools/names/crs_names.json +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/tools/names/dac1_names.json +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/tools/names/dac2a_names.json +0 -0
- {oda_data-2.0.3 → oda_data-2.0.5}/oda_data/tools/sector_lists.py +0 -0
|
@@ -100,7 +100,11 @@ def bilateral_policy_marker(
|
|
|
100
100
|
crs = CRSData(providers=providers, years=years, recipients=recipients)
|
|
101
101
|
|
|
102
102
|
# Read the data and group by provider and purpose
|
|
103
|
-
data = crs.read(
|
|
103
|
+
data = crs.read(
|
|
104
|
+
columns=grouper + [measure],
|
|
105
|
+
additional_filters=filters,
|
|
106
|
+
using_bulk_download=True,
|
|
107
|
+
)
|
|
104
108
|
|
|
105
109
|
# if marker is not_screened, we need to filter out the screened data
|
|
106
110
|
if marker == "not_screened":
|
|
@@ -183,6 +183,7 @@ def spending_by_purpose(
|
|
|
183
183
|
crs.read(
|
|
184
184
|
columns=grouper + [measure],
|
|
185
185
|
additional_filters=filters,
|
|
186
|
+
using_bulk_download=True,
|
|
186
187
|
)
|
|
187
188
|
.groupby(grouper, dropna=False, observed=True)[[measure]]
|
|
188
189
|
.sum()
|
|
@@ -279,7 +280,11 @@ def core_multilateral_contributions_by_provider(
|
|
|
279
280
|
|
|
280
281
|
# Read the data and group by provider and channel
|
|
281
282
|
data = (
|
|
282
|
-
ms.read(
|
|
283
|
+
ms.read(
|
|
284
|
+
columns=cols + [ODASchema.AMOUNT],
|
|
285
|
+
additional_filters=filters,
|
|
286
|
+
using_bulk_download=True,
|
|
287
|
+
)
|
|
283
288
|
.groupby(cols, dropna=False, observed=True)[[ODASchema.AMOUNT]]
|
|
284
289
|
.sum()
|
|
285
290
|
.reset_index()
|
|
@@ -7,6 +7,7 @@ from typing import Any, Dict, Optional
|
|
|
7
7
|
import pandas as pd
|
|
8
8
|
|
|
9
9
|
from oda_data.logger import logger
|
|
10
|
+
from oda_data.tools.names.create_mapping import snake_to_pascal
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
def generate_param_hash(filters: list[tuple]) -> str:
|
|
@@ -48,6 +49,13 @@ class OnDiskCache:
|
|
|
48
49
|
) -> pd.DataFrame | None:
|
|
49
50
|
"""Loads a DataFrame from disk if available and not expired."""
|
|
50
51
|
path = self.get_file_path(dataset_name, param_hash)
|
|
52
|
+
if dataset_name == "MultiSystemData":
|
|
53
|
+
columns = [snake_to_pascal(col) for col in columns] if columns else columns
|
|
54
|
+
filters = (
|
|
55
|
+
[(snake_to_pascal(col), op, val) for col, op, val in filters]
|
|
56
|
+
if filters
|
|
57
|
+
else None
|
|
58
|
+
)
|
|
51
59
|
if not path.exists():
|
|
52
60
|
return None
|
|
53
61
|
if self._is_expired(path):
|
|
@@ -7,6 +7,38 @@ from oda_data.config import ODAPaths
|
|
|
7
7
|
from oda_data.indicators.common import update_mapping_file
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
def snake_to_pascal(name: str, *, keep_single_letter: bool = False) -> str:
|
|
11
|
+
"""
|
|
12
|
+
Convert a snake_case string to PascalCase.
|
|
13
|
+
|
|
14
|
+
Parameters
|
|
15
|
+
----------
|
|
16
|
+
name : str
|
|
17
|
+
The snake_case identifier to convert.
|
|
18
|
+
keep_single_letter : bool, default False
|
|
19
|
+
If True, preserve the underscore that precedes a 1-letter
|
|
20
|
+
segment (e.g. 'aid_t' → 'Aid_T'). If False, drop it
|
|
21
|
+
('aid_t' → 'AidT').
|
|
22
|
+
|
|
23
|
+
Returns
|
|
24
|
+
-------
|
|
25
|
+
str
|
|
26
|
+
The PascalCase version.
|
|
27
|
+
"""
|
|
28
|
+
parts = name.split("_")
|
|
29
|
+
if not keep_single_letter:
|
|
30
|
+
# Simple path: just capitalise everything and join.
|
|
31
|
+
return "".join(p.capitalize() for p in parts)
|
|
32
|
+
|
|
33
|
+
# Preserve “_” before any single-letter trailing part.
|
|
34
|
+
out: list[str] = []
|
|
35
|
+
for part in parts:
|
|
36
|
+
if len(part) == 1 and out:
|
|
37
|
+
out[-1] = out[-1] + "_" + part.upper()
|
|
38
|
+
else:
|
|
39
|
+
out.append(part.capitalize())
|
|
40
|
+
return "".join(out)
|
|
41
|
+
|
|
10
42
|
def _code_name(df: pd.DataFrame, code_col: str, name_col: str) -> dict:
|
|
11
43
|
"""Return a dictionary mapping code to name."""
|
|
12
44
|
return (
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|