nixtla icon indicating copy to clipboard operation
nixtla copied to clipboard

Cross-validating + finetuning on Float32 targets on a Polars DataFrame fails

Open elephaint opened this issue 10 months ago • 2 comments

What happened + What you expected to happen

Cross-validating + finetuning with Polars on a Float32 target array fails. The following code fails, whereas removing the line that casts to Float32 will make the code pass.

Note:

  • On Pandas this code passes (for both Float64 and Float32 target col dtypes);
  • On the forecast endpoint the code passes too (for both Polars and Pandas, and for both Float32 and Float64 dtypes);
  • Without finetuning the code passes too (on all dtypes and engines)
import polars as pl
from utilsforecast.data import generate_series
from nixtla import NixtlaClient

freq = "1d"
df = generate_series(n_series=10, 
                     min_length=1000,
                     max_length=1000,
                     freq=freq, 
                     engine="polars")
df = df.with_columns(pl.col("y").cast(pl.Float32))  

nixtla_client = NixtlaClient()

fcst = nixtla_client.cross_validation(
    df,
    freq=freq,
    h=8,
    finetune_steps=10)

The error it produces is below, indicating an error in converting the request to a contiguous array before we send it.

File c:\Users\ospra\miniconda3\envs\calmecac\lib\site-packages\nixtla\nixtla_client.py:750, in NixtlaClient._make_request(self, client, endpoint, payload, multithreaded_compress)
    [747](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/nixtla/nixtla_client.py:747)         elif isinstance(v, dict):
    [748](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/nixtla/nixtla_client.py:748)             ensure_contiguous_arrays(v)
--> [750](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/nixtla/nixtla_client.py:750) ensure_contiguous_arrays(payload)
    [751](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/nixtla/nixtla_client.py:751) content = orjson.dumps(payload, option=orjson.OPT_SERIALIZE_NUMPY)
    [752](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/nixtla/nixtla_client.py:752) content_size_mb = len(content) / 2**20

File c:\Users\ospra\miniconda3\envs\calmecac\lib\site-packages\nixtla\nixtla_client.py:748, in NixtlaClient._make_request.<locals>.ensure_contiguous_arrays(d)
    [746](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/nixtla/nixtla_client.py:746)     d[k] = [ensure_contiguous_if_array(x) for x in v]
    [747](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/nixtla/nixtla_client.py:747) elif isinstance(v, dict):
--> [748](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/nixtla/nixtla_client.py:748)     ensure_contiguous_arrays(v)

File c:\Users\ospra\miniconda3\envs\calmecac\lib\site-packages\nixtla\nixtla_client.py:744, in NixtlaClient._make_request.<locals>.ensure_contiguous_arrays(d)
    [742](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/nixtla/nixtla_client.py:742) for k, v in d.items():
    [743](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/nixtla/nixtla_client.py:743)     if isinstance(v, np.ndarray):
--> [744](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/nixtla/nixtla_client.py:744)         d[k] = ensure_contiguous_if_array(v)
    [745](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/nixtla/nixtla_client.py:745)     elif isinstance(v, list):
    [746](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/nixtla/nixtla_client.py:746)         d[k] = [ensure_contiguous_if_array(x) for x in v]

File c:\Users\ospra\miniconda3\envs\calmecac\lib\site-packages\nixtla\nixtla_client.py:730, in NixtlaClient._make_request.<locals>.ensure_contiguous_if_array(x)
    [728](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/nixtla/nixtla_client.py:728)     return x
    [729](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/nixtla/nixtla_client.py:729) if np.issubdtype(x.dtype, np.floating):
--> [730](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/nixtla/nixtla_client.py:730)     x = np.nan_to_num(
    [731](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/nixtla/nixtla_client.py:731)         np.ascontiguousarray(x, dtype=np.float32),
    [732](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/nixtla/nixtla_client.py:732)         nan=np.nan,
    [733](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/nixtla/nixtla_client.py:733)         posinf=np.finfo(np.float32).max,
    [734](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/nixtla/nixtla_client.py:734)         neginf=np.finfo(np.float32).min,
    [735](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/nixtla/nixtla_client.py:735)         copy=False,
    [736](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/nixtla/nixtla_client.py:736)     )
    [737](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/nixtla/nixtla_client.py:737) else:
    [738](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/nixtla/nixtla_client.py:738)     x = np.ascontiguousarray(x)

File c:\Users\ospra\miniconda3\envs\calmecac\lib\site-packages\numpy\lib\_type_check_impl.py:480, in nan_to_num(x, copy, nan, posinf, neginf)
    [478](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/numpy/lib/_type_check_impl.py:478) idx_posinf = isposinf(d)
    [479](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/numpy/lib/_type_check_impl.py:479) idx_neginf = isneginf(d)
--> [480](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/numpy/lib/_type_check_impl.py:480) _nx.copyto(d, nan, where=idx_nan)
    [481](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/numpy/lib/_type_check_impl.py:481) _nx.copyto(d, maxf, where=idx_posinf)
    [482](file:///C:/Users/ospra/miniconda3/envs/calmecac/lib/site-packages/numpy/lib/_type_check_impl.py:482) _nx.copyto(d, minf, where=idx_neginf)

ValueError: assignment destination is read-only

Versions / Dependencies

  • python 3.10
  • nixtla 0.6.6
  • numpy 2.0.1
  • polars 1.24.0

elephaint avatar Apr 15 '25 14:04 elephaint

Edit: upgrading polars + Numpy doesn't solve the issue

elephaint avatar Apr 16 '25 07:04 elephaint

Just set copy to true

jmoralez avatar Apr 16 '25 15:04 jmoralez