Skip to content

Commit c8fcfcb

Browse files
PERF: Fixed regression in Series(index=idx) constructor (pandas-dev#20865)
1 parent d274d0b commit c8fcfcb

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

pandas/core/series.py

+14-3
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,11 @@
4141
maybe_cast_to_datetime, maybe_castable,
4242
construct_1d_arraylike_from_scalar,
4343
construct_1d_object_array_from_listlike)
44-
from pandas.core.dtypes.missing import isna, notna, remove_na_arraylike
44+
from pandas.core.dtypes.missing import (
45+
isna,
46+
notna,
47+
remove_na_arraylike,
48+
na_value_for_dtype)
4549

4650
from pandas.core.index import (Index, MultiIndex, InvalidIndexError,
4751
Float64Index, _ensure_index)
@@ -300,16 +304,23 @@ def _init_dict(self, data, index=None, dtype=None):
300304
if data:
301305
keys, values = zip(*compat.iteritems(data))
302306
values = list(values)
307+
elif index is not None:
308+
# fastpath for Series(data=None). Just use broadcasting a scalar
309+
# instead of reindexing.
310+
values = na_value_for_dtype(dtype)
311+
keys = index
303312
else:
304313
keys, values = [], []
305314

306315
# Input is now list-like, so rely on "standard" construction:
307316
s = Series(values, index=keys, dtype=dtype)
308317

309318
# Now we just make sure the order is respected, if any
310-
if index is not None:
319+
if data and index is not None:
311320
s = s.reindex(index, copy=False)
312-
elif not PY36 and not isinstance(data, OrderedDict):
321+
elif not PY36 and not isinstance(data, OrderedDict) and data:
322+
# Need the `and data` to avoid sorting Series(None, index=[...])
323+
# since that isn't really dict-like
313324
try:
314325
s = s.sort_index()
315326
except TypeError:

pandas/tests/series/test_constructors.py

+15
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,21 @@ def test_constructor_nan(self, input_arg):
122122

123123
assert_series_equal(empty, empty2, check_index_type=False)
124124

125+
@pytest.mark.parametrize('dtype', [
126+
'f8', 'i8', 'M8[ns]', 'm8[ns]', 'category', 'object',
127+
'datetime64[ns, UTC]',
128+
])
129+
@pytest.mark.parametrize('index', [None, pd.Index([])])
130+
def test_constructor_dtype_only(self, dtype, index):
131+
# GH-20865
132+
result = pd.Series(dtype=dtype, index=index)
133+
assert result.dtype == dtype
134+
assert len(result) == 0
135+
136+
def test_constructor_no_data_index_order(self):
137+
result = pd.Series(index=['b', 'a', 'c'])
138+
assert result.index.tolist() == ['b', 'a', 'c']
139+
125140
def test_constructor_series(self):
126141
index1 = ['d', 'b', 'a', 'c']
127142
index2 = sorted(index1)

0 commit comments

Comments
 (0)