Skip to content

Commit cd13cb0

Browse files
committed
BUG: fix initialization of Series with dict containing NaN key
closes pandas-dev#18480
1 parent 38f41e6 commit cd13cb0

File tree

3 files changed

+48
-11
lines changed

3 files changed

+48
-11
lines changed

doc/source/whatsnew/v0.22.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -205,4 +205,5 @@ Other
205205

206206
- Improved error message when attempting to use a Python keyword as an identifier in a numexpr query (:issue:`18221`)
207207
- Fixed a bug where creating a Series from an array that contains both tz-naive and tz-aware values will result in a Series whose dtype is tz-aware instead of object (:issue:`16406`)
208+
- Fixed initialization of Series from dict containing NaN as key (:issue:`18480`)
208209
-

pandas/core/series.py

+35-11
Original file line numberDiff line numberDiff line change
@@ -198,18 +198,42 @@ def __init__(self, data=None, index=None, dtype=None, name=None,
198198
data = data.reindex(index, copy=copy)
199199
data = data._data
200200
elif isinstance(data, dict):
201-
if index is None:
202-
if isinstance(data, OrderedDict):
203-
index = Index(data)
201+
if data:
202+
keys, values = zip(*compat.iteritems(data))
203+
keys = Index(list(keys), tupleize_cols=True)
204+
a_values = np.empty(len(values), dtype='object')
205+
# Avoid interpreting list-like elements as 2nd dimension:
206+
for idx, v in enumerate(values):
207+
a_values[idx] = v
208+
try:
209+
values = lib.maybe_convert_objects(a_values)
210+
except:
211+
values = a_values
212+
if index is None:
213+
if isinstance(data, OrderedDict):
214+
order = np.arange(len(keys))
215+
else:
216+
try:
217+
order = keys.argsort()
218+
except TypeError:
219+
order = np.arange(len(keys))
220+
index = keys[order]
204221
else:
205-
index = Index(_try_sort(data))
206-
207-
try:
208-
data = index._get_values_from_dict(data)
209-
except TypeError:
210-
data = ([data.get(i, np.nan) for i in index]
211-
if data else np.nan)
212-
222+
locs = index.get_indexer(keys)
223+
order = - np.ones(len(index), dtype=int)
224+
order[locs] = np.arange(len(keys))
225+
data = values[order]
226+
nan_idxs = np.where(order == -1)[0]
227+
if len(nan_idxs):
228+
if is_integer_dtype(data):
229+
data = data.astype(float)
230+
data[nan_idxs] = np.nan
231+
if any([is_list_like(item) for item in data]):
232+
data = list(data)
233+
else:
234+
if index is None:
235+
index = Index([])
236+
data = np.array([np.nan] * len(index))
213237
elif isinstance(data, SingleBlockManager):
214238
if index is None:
215239
index = data.index

pandas/tests/series/test_constructors.py

+12
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,18 @@ def test_constructor_dict(self):
625625
expected.iloc[1] = 1
626626
assert_series_equal(result, expected)
627627

628+
# GH 18480 - NaN key
629+
d = {1: 'a', 2: 'b', np.nan: 'c'}
630+
result = Series(d).sort_index()
631+
expected = Series(['a', 'b', 'c'], index=[1, 2, np.nan])
632+
assert_series_equal(result, expected)
633+
634+
# Different NaNs:
635+
d = {1: 'a', 2: 'b', float('nan'): 'c', float('nan'): 'd'}
636+
result = Series(d).sort_values()
637+
expected = Series(['a', 'b', 'c', 'd'], index=[1, 2, np.nan, np.nan])
638+
assert_series_equal(result, expected)
639+
628640
def test_constructor_dict_datetime64_index(self):
629641
# GH 9456
630642

0 commit comments

Comments
 (0)