@@ -142,6 +142,7 @@ def historical(
142142 geo_agg : str | None = None ,
143143 time_trunc : str | None = None ,
144144 geo_trunc : str | None = None ,
145+ column_name : str | None = None ,
145146 ) -> pd .DataFrame :
146147 """Fetch historical values as a DataFrame with DatetimeIndex.
147148
@@ -151,6 +152,12 @@ def historical(
151152 When multiple geo_ids are present (e.g. indicator 600 returns data for
152153 several countries), the result is pivoted so each geo becomes a column
153154 named by its geo_name. Use *geo_ids* to filter to specific geos.
155+
156+ Args:
157+ column_name: If provided, rename the output column(s) to this name.
158+ Useful for single-column results where a stable name like
159+ ``"value"`` is preferred over the default geo_name or
160+ indicator ID.
154161 """
155162 base_params : dict [str , Any ] = {
156163 "locale" : locale ,
@@ -250,7 +257,7 @@ def historical(
250257 if existing :
251258 result = result [existing ]
252259
253- return self ._finalize (result )
260+ return self ._finalize (result , column_name = column_name )
254261
255262 def _to_wide (self , values : list [dict ]) -> pd .DataFrame :
256263 """Convert raw API value dicts to wide-format DataFrame.
@@ -283,16 +290,26 @@ def _to_wide(self, values: list[dict]) -> pd.DataFrame:
283290 df = df .drop (columns = geo_drop , errors = "ignore" )
284291 return df
285292
286- def _finalize (self , df : pd .DataFrame ) -> pd .DataFrame :
293+ def _finalize (
294+ self , df : pd .DataFrame , * , column_name : str | None = None ,
295+ ) -> pd .DataFrame :
287296 """Prepare DataFrame for user-facing output.
288297
289298 Cache stores columns as str(geo_id). This method renames them to
290299 human-readable geo_names at the very end, just before returning to
291300 the caller. Single-value/single-geo indicators get the indicator ID.
301+
302+ If ``column_name`` is provided and the result has a single column,
303+ that column is renamed to ``column_name`` (e.g. ``"value"``).
292304 """
293305 if df .empty :
294306 return df
295307
308+ # If caller wants a specific column name and there's a single column, use it
309+ if column_name and len (df .columns ) == 1 :
310+ df = df .rename (columns = {df .columns [0 ]: column_name })
311+ return df
312+
296313 if len (df .columns ) == 1 :
297314 col = df .columns [0 ]
298315 if col == "value" :
@@ -305,11 +322,15 @@ def _finalize(self, df: pd.DataFrame) -> pd.DataFrame:
305322 if rename :
306323 df = df .rename (columns = rename )
307324
325+ # If caller wants a specific column name for multi-column, skip
326+ # (ambiguous which column to rename)
327+ if column_name and len (df .columns ) == 1 :
328+ df = df .rename (columns = {df .columns [0 ]: column_name })
329+ return df
330+
308331 # Single-geo after rename: use indicator ID as column name
309332 if len (df .columns ) == 1 :
310333 col = df .columns [0 ]
311- # If the single column is a geo_name, keep it (user filtered to one geo)
312- # If it's still a geo_id string, rename to indicator ID
313334 if col not in geo_map .values ():
314335 df = df .rename (columns = {col : str (self .id )})
315336
0 commit comments