Spaces:
Sleeping
Sleeping
File size: 1,780 Bytes
558db1e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | import pandas as pd
import numpy as np
import json
import datetime
import decimal
def _ds(series, n=250):
"""Downsamples a time series to a maximum of `n` points for frontend rendering speed."""
if series is None:
return series
# Note: Ensure it's a pandas Series to prevent .iloc crashes on raw lists/arrays
if not isinstance(series, (pd.Series, pd.DataFrame)):
series = pd.Series(series)
elif not series.index.is_unique:
# Note: Deduplicate index to prevent Chart.js from rendering zig-zag lines
series = series[~series.index.duplicated(keep='last')]
if len(series) <= n:
return series
# Note: Use uniform np.linspace to avoid discontinuity seams from concatenating tails
idx = np.round(np.linspace(0, len(series) - 1, n)).astype(int)
return series.iloc[idx]
def safe_json(obj):
"""
Safely serializes deep dictionaries containing NumPy/Pandas native types,
Datetimes, NaNs, and NaTs for Chart.js parsing.
"""
def _fix(o):
if o is None or o is pd.NA or o is pd.NaT:
return None
if isinstance(o, decimal.Decimal):
return float(o)
if isinstance(o, (float, np.floating)):
return None if not np.isfinite(o) else float(o)
if isinstance(o, (int, np.integer)):
return int(o)
if isinstance(o, (pd.Timestamp, datetime.datetime, datetime.date)):
return str(o)
if isinstance(o, dict):
return {k: _fix(v) for k, v in o.items()}
if isinstance(o, (list, tuple, np.ndarray, pd.Series, pd.Index)):
return [_fix(v) for v in o]
return o
return json.dumps(_fix(obj))
|