@@ -492,15 +492,18 @@ def _obtain_time_series_data_frame(time_series_data):
492492
493493 # We must replace NaN with None, otherwise the JSON encoder will
494494 # save 'NaN' as the string and this will get rejected by our schema
495- # on any subsequent loads
496- # Note we can't use .fillna(None) due to this issue:
497- # https://github.com/pydata/pandas/issues/1972
495+ # on any subsequent loads.
496+ # Pandas 3.0 infers 'str' dtype for these columns, and assigning
497+ # NaN on a str-dtype column coerces to the string 'nan'. Force
498+ # object dtype and map both real NaN and stringified 'nan' back
499+ # to None so downstream JSON serialization writes null.
498500 df_keys = set (df_odict [worm_id ].columns .get_level_values ('key' ))
499501 for k in ['head' , 'ventral' ]:
500502 if k in df_keys :
501- cur_slice = df_odict [worm_id ].loc [:, idx [:, k , :]]
502- df_odict [worm_id ].loc [:, idx [:, k , :]] = \
503- cur_slice .fillna (value = np .nan )
503+ df = df_odict [worm_id ]
504+ for col in [c for c in df .columns if c [1 ] == k ]:
505+ s = df [col ].astype (object )
506+ df [col ] = s .where (s .notna () & (s != 'nan' ), None )
504507
505508 # Make sure aspect_size is a float, since only floats are nullable.
506509 # Replace the column whole rather than assigning via .loc[]; pandas
0 commit comments