Skip to content

Commit 736702a

Browse files
Julian-HarbeckJulian Harbeck
andauthored
BUG: Stop item_from_zerodim from converting subclasses of np.ndarray to float (#62999)
Co-authored-by: Julian Harbeck <[email protected]>
1 parent 704d990 commit 736702a

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

pandas/_libs/lib.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ def item_from_zerodim(val: object) -> object:
322322
>>> item_from_zerodim(np.array([1]))
323323
array([1])
324324
"""
325-
if cnp.PyArray_IsZeroDim(val):
325+
if cnp.PyArray_IsZeroDim(val) and cnp.PyArray_CheckExact(val):
326326
return cnp.PyArray_ToScalar(cnp.PyArray_DATA(val), val)
327327
return val
328328

pandas/tests/libs/test_lib.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,3 +307,52 @@ def test_ensure_string_array_list_of_lists():
307307
# Each item in result should still be a list, not a stringified version
308308
expected = np.array(["['t', 'e', 's', 't']", "['w', 'o', 'r', 'd']"], dtype=object)
309309
tm.assert_numpy_array_equal(result, expected)
310+
311+
312+
def test_item_from_zerodim_for_subclasses():
313+
# GH#62981 Ensure item_from_zerodim preserves subclasses of ndarray
314+
# Define a custom ndarray subclass
315+
class TestArray(np.ndarray):
316+
def __new__(cls, input_array):
317+
return np.asarray(input_array).view(cls)
318+
319+
def __array_finalize__(self, obj) -> None:
320+
self._is_test_array = True
321+
322+
# Define test data
323+
val_0_dim = 1
324+
val_1_dim = [1, 2, 3]
325+
326+
# 0-dim and 1-dim numpy arrays
327+
arr_0_dim = np.array(val_0_dim)
328+
arr_1_dim = np.array(val_1_dim)
329+
330+
# 0-dim and 1-dim TestArray arrays
331+
test_arr_0_dim = TestArray(val_0_dim)
332+
test_arr_1_dim = TestArray(val_1_dim)
333+
334+
# Check that behavior did not change for regular numpy arrays
335+
# Test with regular numpy 0-dim array
336+
result = lib.item_from_zerodim(arr_0_dim)
337+
expected = val_0_dim
338+
assert result == expected
339+
assert np.isscalar(result)
340+
341+
# Test with regular numpy 1-dim array
342+
result = lib.item_from_zerodim(arr_1_dim)
343+
expected = arr_1_dim
344+
tm.assert_numpy_array_equal(result, expected)
345+
assert isinstance(result, np.ndarray)
346+
347+
# Check that behaviour for subclasses now is as expected
348+
# Test with TestArray 0-dim array
349+
result = lib.item_from_zerodim(test_arr_0_dim)
350+
expected = test_arr_0_dim
351+
assert result == expected
352+
assert isinstance(result, TestArray)
353+
354+
# Test with TestArray 1-dim array
355+
result = lib.item_from_zerodim(test_arr_1_dim)
356+
expected = test_arr_1_dim
357+
assert np.all(result == expected)
358+
assert isinstance(result, TestArray)

0 commit comments

Comments
 (0)