@@ -152,7 +152,16 @@ cdef _write_array(
152
152
153
153
if attr .isvar :
154
154
try :
155
- buffer , offsets = array_to_buffer (values [i ], True , False )
155
+ if attr .isnullable :
156
+ if (np .issubdtype (attr .dtype , np .unicode_ )
157
+ or np .issubdtype (attr .dtype , np .string_ )
158
+ or np .issubdtype (attr .dtype , np .bytes_ )):
159
+ attr_val = np .array (["" if v is None else v for v in values [i ]])
160
+ else :
161
+ attr_val = np .nan_to_num (values [i ])
162
+ else :
163
+ attr_val = values [i ]
164
+ buffer , offsets = array_to_buffer (attr_val , True , False )
156
165
except Exception as exc :
157
166
raise type (exc )(f"Failed to convert buffer for attribute: '{ attr .name } '" ) from exc
158
167
buffer_offsets_sizes [i ] = offsets .nbytes
@@ -2241,6 +2250,7 @@ cdef class DenseArrayImpl(Array):
2241
2250
selection_tuple = (selection ,) if not isinstance (selection , tuple ) else selection
2242
2251
self ._setitem_impl (selection , val , dict ())
2243
2252
2253
+
2244
2254
def _setitem_impl (self , object selection , object val , dict nullmaps ):
2245
2255
"""Implementation for setitem with optional support for validity bitmaps."""
2246
2256
from .subarray import Subarray
@@ -2300,16 +2310,33 @@ cdef class DenseArrayImpl(Array):
2300
2310
# ensure that the value is array-convertible, for example: pandas.Series
2301
2311
attr_val = np .asarray (attr_val )
2302
2312
if attr .isnullable and name not in nullmaps :
2303
- nullmaps [name ] = np .array ([int (v is not None ) for v in attr_val ], dtype = np .uint8 )
2313
+ nullmaps [name ] = np .array (
2314
+ [int (v is not None ) for v in attr_val ],
2315
+ dtype = np .uint8
2316
+ )
2304
2317
else :
2305
2318
if (np .issubdtype (attr .dtype , np .string_ ) and not
2306
2319
(np .issubdtype (attr_val .dtype , np .string_ ) or attr_val .dtype == np .dtype ('O' ))):
2307
2320
raise ValueError ("Cannot write a string value to non-string "
2308
2321
"typed attribute '{}'!" .format (name ))
2309
2322
2310
2323
if attr .isnullable and name not in nullmaps :
2311
- nullmaps [name ] = ~ np .ma .masked_invalid (attr_val ).mask
2312
- attr_val = np .nan_to_num (attr_val )
2324
+ try :
2325
+ nullmaps [name ] = ~ np .ma .masked_invalid (attr_val ).mask
2326
+ except Exception as exc :
2327
+ attr_val = np .asarray (attr_val )
2328
+ nullmaps [name ] = np .array (
2329
+ [int (v is not None ) for v in attr_val ],
2330
+ dtype = np .uint8
2331
+ )
2332
+
2333
+ if np .issubdtype (attr .dtype , np .string_ ):
2334
+ attr_val = np .array (
2335
+ ["" if v is None else v for v in attr_val ])
2336
+ else :
2337
+ attr_val = np .nan_to_num (attr_val )
2338
+ attr_val = np .array (
2339
+ [0 if v is None else v for v in attr_val ])
2313
2340
attr_val = np .ascontiguousarray (attr_val , dtype = attr .dtype )
2314
2341
except Exception as exc :
2315
2342
raise ValueError (f"NumPy array conversion check failed for attr '{ name } '" ) from exc
@@ -2335,7 +2362,7 @@ cdef class DenseArrayImpl(Array):
2335
2362
# ensure that the value is array-convertible, for example: pandas.Series
2336
2363
val = np .asarray (val )
2337
2364
if attr .isnullable and name not in nullmaps :
2338
- nullmaps [name ] = np .array ([int (v is not None ) for v in val ], dtype = np .uint8 )
2365
+ nullmaps [name ] = np .array ([int (v is None ) for v in val ], dtype = np .uint8 )
2339
2366
else :
2340
2367
if (np .issubdtype (attr .dtype , np .string_ ) and not
2341
2368
(np .issubdtype (val .dtype , np .string_ ) or val .dtype == np .dtype ('O' ))):
@@ -2817,22 +2844,34 @@ def _setitem_impl_sparse(self: Array, selection, val, dict nullmaps):
2817
2844
attr_val = val [name ]
2818
2845
2819
2846
try :
2847
+ # ensure that the value is array-convertible, for example: pandas.Series
2848
+ attr_val = np .asarray (attr_val )
2849
+
2820
2850
if attr .isvar :
2821
- # ensure that the value is array-convertible, for example: pandas.Series
2822
- attr_val = np .asarray (attr_val )
2823
2851
if attr .isnullable and name not in nullmaps :
2824
- nullmaps [name ] = np .array ([int (v is not None ) for v in attr_val ], dtype = np .uint8 )
2852
+ nullmaps [name ] = np .array (
2853
+ [int (v is not None ) for v in attr_val ], dtype = np .uint8 )
2825
2854
else :
2826
- if (np .issubdtype (attr .dtype , np .string_ ) and not
2827
- (np .issubdtype (attr_val .dtype , np .string_ ) or attr_val .dtype == np .dtype ('O' ))):
2855
+ if (np .issubdtype (attr .dtype , np .string_ )
2856
+ and not (np .issubdtype (attr_val .dtype , np .string_ )
2857
+ or attr_val .dtype == np .dtype ('O' ))):
2828
2858
raise ValueError ("Cannot write a string value to non-string "
2829
- "typed attribute '{}'!" .format (name ))
2859
+ "typed attribute '{}'!" .format (name ))
2830
2860
2831
2861
if attr .isnullable and name not in nullmaps :
2832
- nullmaps [name ] = ~ np .ma .masked_invalid (attr_val ).mask
2833
- attr_val = np .nan_to_num (attr_val )
2862
+ try :
2863
+ nullmaps [name ] = ~ np .ma .masked_invalid (attr_val ).mask
2864
+ except Exception as exc :
2865
+ nullmaps [name ] = np .array (
2866
+ [int (v is not None ) for v in attr_val ], dtype = np .uint8 )
2867
+
2868
+ if np .issubdtype (attr .dtype , np .string_ ):
2869
+ attr_val = np .array (["" if v is None else v for v in attr_val ])
2870
+ else :
2871
+ attr_val = np .nan_to_num (attr_val )
2872
+ attr_val = np .array ([0 if v is None else v for v in attr_val ])
2834
2873
attr_val = np .ascontiguousarray (attr_val , dtype = attr .dtype )
2835
-
2874
+
2836
2875
except Exception as exc :
2837
2876
raise ValueError (f"NumPy array conversion check failed for attr '{ name } '" ) from exc
2838
2877
0 commit comments