@@ -53,7 +53,7 @@ def to_scalar_or_list(v):
53
53
return v
54
54
55
55
56
- def copy_to_readonly_numpy_array_or_list (v , kind = None , force_numeric = False ):
56
+ def copy_to_readonly_numpy_array (v , kind = None , force_numeric = False ):
57
57
"""
58
58
Convert an array-like value into a read-only numpy array
59
59
@@ -94,7 +94,6 @@ def copy_to_readonly_numpy_array_or_list(v, kind=None, force_numeric=False):
94
94
"i" : "int32" ,
95
95
"f" : "float64" ,
96
96
"O" : "object" ,
97
- "U" : "U" ,
98
97
}
99
98
100
99
# Handle pandas Series and Index objects
@@ -119,12 +118,18 @@ def copy_to_readonly_numpy_array_or_list(v, kind=None, force_numeric=False):
119
118
if not isinstance (v , np .ndarray ):
120
119
# v has its own logic on how to convert itself into a numpy array
121
120
if is_numpy_convertable (v ):
122
- return copy_to_readonly_numpy_array_or_list (
121
+ return copy_to_readonly_numpy_array (
123
122
np .array (v ), kind = kind , force_numeric = force_numeric
124
123
)
125
124
else :
126
125
# v is not homogenous array
127
- return [to_scalar_or_list (e ) for e in v ]
126
+ v_list = [to_scalar_or_list (e ) for e in v ]
127
+
128
+ # Lookup dtype for requested kind, if any
129
+ dtype = kind_default_dtypes .get (first_kind , None )
130
+
131
+ # construct new array from list
132
+ new_v = np .array (v_list , order = "C" , dtype = dtype )
128
133
elif v .dtype .kind in numeric_kinds :
129
134
# v is a homogenous numeric array
130
135
if kind and v .dtype .kind not in kind :
@@ -135,12 +140,6 @@ def copy_to_readonly_numpy_array_or_list(v, kind=None, force_numeric=False):
135
140
else :
136
141
# Either no kind was requested or requested kind is satisfied
137
142
new_v = np .ascontiguousarray (v .copy ())
138
- elif v .dtype .kind == "O" :
139
- if kind :
140
- dtype = kind_default_dtypes .get (first_kind , None )
141
- return np .array (v , dtype = dtype )
142
- else :
143
- return v .tolist ()
144
143
else :
145
144
# v is a non-numeric homogenous array
146
145
new_v = v .copy ()
@@ -155,12 +154,12 @@ def copy_to_readonly_numpy_array_or_list(v, kind=None, force_numeric=False):
155
154
if "U" not in kind :
156
155
# Force non-numeric arrays to have object type
157
156
# --------------------------------------------
158
- # Here we make sure that non-numeric arrays become lists
159
- # This works around cases like np.array([1, 2, '3']) where
157
+ # Here we make sure that non-numeric arrays have the object
158
+ # datatype. This works around cases like np.array([1, 2, '3']) where
160
159
# numpy converts the integers to strings and returns array of dtype
161
160
# '<U21'
162
161
if new_v .dtype .kind not in ["u" , "i" , "f" , "O" , "M" ]:
163
- return v . tolist ( )
162
+ new_v = np . array ( v , dtype = "object" )
164
163
165
164
# Set new array to be read-only
166
165
# -----------------------------
@@ -399,7 +398,7 @@ def validate_coerce(self, v):
399
398
# Pass None through
400
399
pass
401
400
elif is_homogeneous_array (v ):
402
- v = copy_to_readonly_numpy_array_or_list (v )
401
+ v = copy_to_readonly_numpy_array (v )
403
402
elif is_simple_array (v ):
404
403
v = to_scalar_or_list (v )
405
404
else :
@@ -610,7 +609,7 @@ def validate_coerce(self, v):
610
609
self .raise_invalid_elements (invalid_els [:10 ])
611
610
612
611
if is_homogeneous_array (v ):
613
- v = copy_to_readonly_numpy_array_or_list (v )
612
+ v = copy_to_readonly_numpy_array (v )
614
613
else :
615
614
v = to_scalar_or_list (v )
616
615
else :
@@ -766,7 +765,7 @@ def validate_coerce(self, v):
766
765
elif self .array_ok and is_homogeneous_array (v ):
767
766
np = get_module ("numpy" )
768
767
try :
769
- v_array = copy_to_readonly_numpy_array_or_list (v , force_numeric = True )
768
+ v_array = copy_to_readonly_numpy_array (v , force_numeric = True )
770
769
except (ValueError , TypeError , OverflowError ):
771
770
self .raise_invalid_val (v )
772
771
@@ -893,7 +892,7 @@ def validate_coerce(self, v):
893
892
pass
894
893
elif self .array_ok and is_homogeneous_array (v ):
895
894
np = get_module ("numpy" )
896
- v_array = copy_to_readonly_numpy_array_or_list (
895
+ v_array = copy_to_readonly_numpy_array (
897
896
v , kind = ("i" , "u" ), force_numeric = True
898
897
)
899
898
@@ -1054,7 +1053,25 @@ def validate_coerce(self, v):
1054
1053
if invalid_els :
1055
1054
self .raise_invalid_elements (invalid_els )
1056
1055
1057
- if is_simple_array (v ) or is_homogeneous_array (v ):
1056
+ if is_homogeneous_array (v ):
1057
+ np = get_module ("numpy" )
1058
+
1059
+ # If not strict, let numpy cast elements to strings
1060
+ v = copy_to_readonly_numpy_array (v , kind = "U" )
1061
+
1062
+ # Check no_blank
1063
+ if self .no_blank :
1064
+ invalid_els = v [v == "" ][:10 ].tolist ()
1065
+ if invalid_els :
1066
+ self .raise_invalid_elements (invalid_els )
1067
+
1068
+ # Check values
1069
+ if self .values :
1070
+ invalid_inds = np .logical_not (np .isin (v , self .values ))
1071
+ invalid_els = v [invalid_inds ][:10 ].tolist ()
1072
+ if invalid_els :
1073
+ self .raise_invalid_elements (invalid_els )
1074
+ elif is_simple_array (v ):
1058
1075
if not self .strict :
1059
1076
v = [StringValidator .to_str_or_unicode_or_none (e ) for e in v ]
1060
1077
@@ -1331,12 +1348,8 @@ def validate_coerce(self, v, should_raise=True):
1331
1348
# Pass None through
1332
1349
pass
1333
1350
elif self .array_ok and is_homogeneous_array (v ):
1334
- v = copy_to_readonly_numpy_array_or_list (v )
1335
- if (
1336
- not isinstance (v , list )
1337
- and self .numbers_allowed ()
1338
- and v .dtype .kind in ["u" , "i" , "f" ]
1339
- ):
1351
+ v = copy_to_readonly_numpy_array (v )
1352
+ if self .numbers_allowed () and v .dtype .kind in ["u" , "i" , "f" ]:
1340
1353
# Numbers are allowed and we have an array of numbers.
1341
1354
# All good
1342
1355
pass
@@ -1350,9 +1363,9 @@ def validate_coerce(self, v, should_raise=True):
1350
1363
1351
1364
# ### Check that elements have valid colors types ###
1352
1365
elif self .numbers_allowed () or invalid_els :
1353
- v = copy_to_readonly_numpy_array_or_list (validated_v , kind = "O" )
1366
+ v = copy_to_readonly_numpy_array (validated_v , kind = "O" )
1354
1367
else :
1355
- v = copy_to_readonly_numpy_array_or_list (validated_v , kind = "U" )
1368
+ v = copy_to_readonly_numpy_array (validated_v , kind = "U" )
1356
1369
elif self .array_ok and is_simple_array (v ):
1357
1370
validated_v = [self .validate_coerce (e , should_raise = False ) for e in v ]
1358
1371
@@ -1867,7 +1880,7 @@ def validate_coerce(self, v):
1867
1880
self .raise_invalid_elements (invalid_els )
1868
1881
1869
1882
if is_homogeneous_array (v ):
1870
- v = copy_to_readonly_numpy_array_or_list (validated_v , kind = "U" )
1883
+ v = copy_to_readonly_numpy_array (validated_v , kind = "U" )
1871
1884
else :
1872
1885
v = to_scalar_or_list (v )
1873
1886
else :
@@ -1915,7 +1928,7 @@ def validate_coerce(self, v):
1915
1928
# Pass None through
1916
1929
pass
1917
1930
elif self .array_ok and is_homogeneous_array (v ):
1918
- v = copy_to_readonly_numpy_array_or_list (v , kind = "O" )
1931
+ v = copy_to_readonly_numpy_array (v , kind = "O" )
1919
1932
elif self .array_ok and is_simple_array (v ):
1920
1933
v = to_scalar_or_list (v )
1921
1934
return v
0 commit comments