Skip to content

Commit 441beef

Browse files
authored
BUG: Series(range_obj_outside_i8_bounds) (#41579)
1 parent 4f601b1 commit 441beef

File tree

4 files changed

+53
-2
lines changed

4 files changed

+53
-2
lines changed

doc/source/whatsnew/v1.3.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -1055,6 +1055,7 @@ Other
10551055
- Bug in :meth:`DataFrame.agg()` not sorting the aggregated axis in the order of the provided aggragation functions when one or more aggregation function fails to produce results (:issue:`33634`)
10561056
- Bug in :meth:`DataFrame.clip` not interpreting missing values as no threshold (:issue:`40420`)
10571057
- Bug in :class:`Series` backed by :class:`DatetimeArray` or :class:`TimedeltaArray` sometimes failing to set the array's ``freq`` to ``None`` (:issue:`41425`)
1058+
- Bug in creating a :class:`Series` from a ``range`` object that does not fit in the bounds of ``int64`` dtype (:issue:`30173`)
10581059

10591060
.. ---------------------------------------------------------------------------
10601061

pandas/core/construction.py

+20-1
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ def sanitize_array(
502502
data = lib.item_from_zerodim(data)
503503
elif isinstance(data, range):
504504
# GH#16804
505-
data = np.arange(data.start, data.stop, data.step, dtype="int64")
505+
data = range_to_ndarray(data)
506506
copy = False
507507

508508
if not is_list_like(data):
@@ -569,6 +569,25 @@ def sanitize_array(
569569
return subarr
570570

571571

572+
def range_to_ndarray(rng: range) -> np.ndarray:
573+
"""
574+
Cast a range object to ndarray.
575+
"""
576+
# GH#30171 perf avoid realizing range as a list in np.array
577+
try:
578+
arr = np.arange(rng.start, rng.stop, rng.step, dtype="int64")
579+
except OverflowError:
580+
# GH#30173 handling for ranges that overflow int64
581+
if (rng.start >= 0 and rng.step > 0) or (rng.stop >= 0 and rng.step < 0):
582+
try:
583+
arr = np.arange(rng.start, rng.stop, rng.step, dtype="uint64")
584+
except OverflowError:
585+
arr = construct_1d_object_array_from_listlike(list(rng))
586+
else:
587+
arr = construct_1d_object_array_from_listlike(list(rng))
588+
return arr
589+
590+
572591
def _sanitize_ndim(
573592
result: ArrayLike, data, dtype: DtypeObj | None, index: Index | None
574593
) -> ArrayLike:

pandas/core/internals/construction.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
from pandas.core.construction import (
6767
ensure_wrapped_if_datetimelike,
6868
extract_array,
69+
range_to_ndarray,
6970
sanitize_array,
7071
)
7172
from pandas.core.indexes import base as ibase
@@ -530,7 +531,7 @@ def _prep_ndarray(values, copy: bool = True) -> np.ndarray:
530531
if len(values) == 0:
531532
return np.empty((0, 0), dtype=object)
532533
elif isinstance(values, range):
533-
arr = np.arange(values.start, values.stop, values.step, dtype="int64")
534+
arr = range_to_ndarray(values)
534535
return arr[..., np.newaxis]
535536

536537
def convert(v):

pandas/tests/series/test_constructors.py

+30
Original file line numberDiff line numberDiff line change
@@ -1525,6 +1525,36 @@ def test_constructor_range_dtype(self, dtype):
15251525
result = Series(range(5), dtype=dtype)
15261526
tm.assert_series_equal(result, expected)
15271527

1528+
def test_constructor_range_overflows(self):
1529+
# GH#30173 range objects that overflow int64
1530+
rng = range(2 ** 63, 2 ** 63 + 4)
1531+
ser = Series(rng)
1532+
expected = Series(list(rng))
1533+
tm.assert_series_equal(ser, expected)
1534+
assert list(ser) == list(rng)
1535+
assert ser.dtype == np.uint64
1536+
1537+
rng2 = range(2 ** 63 + 4, 2 ** 63, -1)
1538+
ser2 = Series(rng2)
1539+
expected2 = Series(list(rng2))
1540+
tm.assert_series_equal(ser2, expected2)
1541+
assert list(ser2) == list(rng2)
1542+
assert ser2.dtype == np.uint64
1543+
1544+
rng3 = range(-(2 ** 63), -(2 ** 63) - 4, -1)
1545+
ser3 = Series(rng3)
1546+
expected3 = Series(list(rng3))
1547+
tm.assert_series_equal(ser3, expected3)
1548+
assert list(ser3) == list(rng3)
1549+
assert ser3.dtype == object
1550+
1551+
rng4 = range(2 ** 73, 2 ** 73 + 4)
1552+
ser4 = Series(rng4)
1553+
expected4 = Series(list(rng4))
1554+
tm.assert_series_equal(ser4, expected4)
1555+
assert list(ser4) == list(rng4)
1556+
assert ser4.dtype == object
1557+
15281558
def test_constructor_tz_mixed_data(self):
15291559
# GH 13051
15301560
dt_list = [

0 commit comments

Comments
 (0)