Skip to content

Commit 1ee5832

Browse files
authored
PERF: Series(dict) returns RangeIndex when possible (#58118)
1 parent 308b773 commit 1ee5832

File tree

4 files changed

+13
-4
lines changed

4 files changed

+13
-4
lines changed

doc/source/whatsnew/v3.0.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ Performance improvements
297297
~~~~~~~~~~~~~~~~~~~~~~~~
298298
- :attr:`Categorical.categories` returns a :class:`RangeIndex` columns instead of an :class:`Index` if the constructed ``values`` was a ``range``. (:issue:`57787`)
299299
- :class:`DataFrame` returns a :class:`RangeIndex` columns when possible when ``data`` is a ``dict`` (:issue:`57943`)
300+
- :class:`Series` returns a :class:`RangeIndex` index when possible when ``data`` is a ``dict`` (:issue:`58118`)
300301
- :func:`concat` returns a :class:`RangeIndex` level in the :class:`MultiIndex` result when ``keys`` is a ``range`` or :class:`RangeIndex` (:issue:`57542`)
301302
- :meth:`RangeIndex.append` returns a :class:`RangeIndex` instead of a :class:`Index` when appending values that could continue the :class:`RangeIndex` (:issue:`57467`)
302303
- :meth:`Series.str.extract` returns a :class:`RangeIndex` columns instead of an :class:`Index` column when possible (:issue:`57542`)

pandas/core/indexes/base.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -7144,7 +7144,10 @@ def maybe_sequence_to_range(sequence) -> Any | range:
71447144
return sequence
71457145
if len(sequence) == 0:
71467146
return range(0)
7147-
np_sequence = np.asarray(sequence, dtype=np.int64)
7147+
try:
7148+
np_sequence = np.asarray(sequence, dtype=np.int64)
7149+
except OverflowError:
7150+
return sequence
71487151
diff = np_sequence[1] - np_sequence[0]
71497152
if diff == 0:
71507153
return sequence

pandas/core/series.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@
132132
PeriodIndex,
133133
default_index,
134134
ensure_index,
135+
maybe_sequence_to_range,
135136
)
136137
import pandas.core.indexes.base as ibase
137138
from pandas.core.indexes.multi import maybe_droplevels
@@ -538,16 +539,14 @@ def _init_dict(
538539
_data : BlockManager for the new Series
539540
index : index for the new Series
540541
"""
541-
keys: Index | tuple
542-
543542
# Looking for NaN in dict doesn't work ({np.nan : 1}[float('nan')]
544543
# raises KeyError), so we iterate the entire dict, and align
545544
if data:
546545
# GH:34717, issue was using zip to extract key and values from data.
547546
# using generators in effects the performance.
548547
# Below is the new way of extracting the keys and values
549548

550-
keys = tuple(data.keys())
549+
keys = maybe_sequence_to_range(tuple(data.keys()))
551550
values = list(data.values()) # Generating list of values- faster way
552551
elif index is not None:
553552
# fastpath for Series(data=None). Just use broadcasting a scalar

pandas/tests/series/test_constructors.py

+6
Original file line numberDiff line numberDiff line change
@@ -2251,3 +2251,9 @@ def test_series_with_complex_nan(input_list):
22512251
result = Series(ser.array)
22522252
assert ser.dtype == "complex128"
22532253
tm.assert_series_equal(ser, result)
2254+
2255+
2256+
def test_dict_keys_rangeindex():
2257+
result = Series({0: 1, 1: 2})
2258+
expected = Series([1, 2], index=RangeIndex(2))
2259+
tm.assert_series_equal(result, expected, check_index_type=True)

0 commit comments

Comments
 (0)