Skip to content

Commit 625ee94

Browse files
committed
BUG: Fixed bug in reset_index with NaN in a multi-index (GH3586_)
1 parent d9dc1cb commit 625ee94

File tree

3 files changed

+35
-5
lines changed

3 files changed

+35
-5
lines changed

RELEASE.rst

+2
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ pandas 0.11.1
103103
- Fix ``.diff`` on datelike and timedelta operations (GH3100_)
104104
- ``combine_first`` not returning the same dtype in cases where it can (GH3552_)
105105
- Fixed bug with ``Panel.transpose`` argument aliases (GH3556_)
106+
- Fixed bug in reset_index with ``NaN`` in a multi-index (GH3586_)
106107

107108
.. _GH3164: https://github.com/pydata/pandas/issues/3164
108109
.. _GH2786: https://github.com/pydata/pandas/issues/2786
@@ -140,6 +141,7 @@ pandas 0.11.1
140141
.. _GH3492: https://github.com/pydata/pandas/issues/3492
141142
.. _GH3552: https://github.com/pydata/pandas/issues/3552
142143
.. _GH3562: https://github.com/pydata/pandas/issues/3562
144+
.. _GH3586: https://github.com/pydata/pandas/issues/3586
143145
.. _GH3493: https://github.com/pydata/pandas/issues/3493
144146
.. _GH3556: https://github.com/pydata/pandas/issues/3556
145147

pandas/core/frame.py

+14-5
Original file line numberDiff line numberDiff line change
@@ -2808,9 +2808,18 @@ def reset_index(self, level=None, drop=False, inplace=False, col_level=0,
28082808
else:
28092809
new_obj = self.copy()
28102810

2811-
def _maybe_cast(values):
2811+
def _maybe_cast(values, labels=None):
2812+
28122813
if values.dtype == np.object_:
28132814
values = lib.maybe_convert_objects(values)
2815+
2816+
# if we have the labels, extract the values with a mask
2817+
if labels is not None:
2818+
mask = labels == -1
2819+
values = values.take(labels)
2820+
if mask.any():
2821+
values, changed = com._maybe_upcast_putmask(values,mask,np.nan)
2822+
28142823
return values
28152824

28162825
new_index = np.arange(len(new_obj))
@@ -2843,9 +2852,9 @@ def _maybe_cast(values):
28432852
col_name = tuple(name_lst)
28442853

28452854
# to ndarray and maybe infer different dtype
2846-
level_values = _maybe_cast(lev.values)
2855+
level_values = _maybe_cast(lev.values, lab)
28472856
if level is None or i in level:
2848-
new_obj.insert(0, col_name, level_values.take(lab))
2857+
new_obj.insert(0, col_name, level_values)
28492858

28502859
elif not drop:
28512860
name = self.index.name
@@ -2865,8 +2874,8 @@ def _maybe_cast(values):
28652874
self.index.tz is not None):
28662875
values = self.index.asobject
28672876
else:
2868-
values = self.index.values
2869-
new_obj.insert(0, name, _maybe_cast(values))
2877+
values = _maybe_cast(self.index.values)
2878+
new_obj.insert(0, name, values)
28702879

28712880
new_obj.index = new_index
28722881
if not inplace:

pandas/tests/test_indexing.py

+19
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,25 @@ def test_indexing_mixed_frame_bug(self):
799799
self.assert_(df.iloc[0,2] == '-----')
800800

801801
#if I look at df, then element [0,2] equals '_'. If instead I type df.ix[idx,'test'], I get '-----', finally by typing df.iloc[0,2] I get '_'.
802+
803+
804+
def test_set_index_nan(self):
805+
806+
# GH 3586
807+
df = DataFrame({'PRuid': {17: 'nonQC', 18: 'nonQC', 19: 'nonQC', 20: '10', 21: '11', 22: '12', 23: '13',
808+
24: '24', 25: '35', 26: '46', 27: '47', 28: '48', 29: '59', 30: '10'},
809+
'QC': {17: 0.0, 18: 0.0, 19: 0.0, 20: nan, 21: nan, 22: nan, 23: nan, 24: 1.0, 25: nan,
810+
26: nan, 27: nan, 28: nan, 29: nan, 30: nan},
811+
'data': {17: 7.9544899999999998, 18: 8.0142609999999994, 19: 7.8591520000000008, 20: 0.86140349999999999,
812+
21: 0.87853110000000001, 22: 0.8427041999999999, 23: 0.78587700000000005, 24: 0.73062459999999996,
813+
25: 0.81668560000000001, 26: 0.81927080000000008, 27: 0.80705009999999999, 28: 0.81440240000000008,
814+
29: 0.80140849999999997, 30: 0.81307740000000006},
815+
'year': {17: 2006, 18: 2007, 19: 2008, 20: 1985, 21: 1985, 22: 1985, 23: 1985,
816+
24: 1985, 25: 1985, 26: 1985, 27: 1985, 28: 1985, 29: 1985, 30: 1986}}).reset_index()
817+
818+
result = df.set_index(['year','PRuid','QC']).reset_index().reindex(columns=df.columns)
819+
assert_frame_equal(result,df)
820+
802821

803822
if __name__ == '__main__':
804823
import nose

0 commit comments

Comments
 (0)