Skip to content

Commit b5096eb

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

File tree

3 files changed

+45
-11
lines changed

3 files changed

+45
-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

+32-11
Original file line numberDiff line numberDiff line change
@@ -198,18 +198,39 @@ 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+
values = np.asarray(values, dtype='object')
205+
try:
206+
values = lib.maybe_convert_objects(values)
207+
except:
208+
pass
209+
if index is None:
210+
if isinstance(data, OrderedDict):
211+
order = np.arange(len(keys))
212+
else:
213+
try:
214+
order = keys.argsort()
215+
except TypeError:
216+
order = np.arange(len(keys))
217+
index = keys[order]
204218
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-
219+
locs = index.get_indexer(keys)
220+
order = - np.ones(len(index), dtype=int)
221+
order[locs] = np.arange(len(keys))
222+
data = values[order]
223+
nan_idxs = np.where(order == -1)[0]
224+
if len(nan_idxs):
225+
if is_integer_dtype(data):
226+
data = data.astype(float)
227+
data[nan_idxs] = np.nan
228+
else:
229+
if index is None:
230+
index = Index([])
231+
data = np.array([np.nan] * len(index))
232+
if any([is_list_like(item) for item in data]):
233+
data = list(data)
213234
elif isinstance(data, SingleBlockManager):
214235
if index is None:
215236
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)