diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 5991ec825c841..16162b699bfd1 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -4367,6 +4367,10 @@ def unstack(self, level=-1, fill_value=None): Name to use for the 'value' column. col_level : int or string, optional If columns are a MultiIndex then use this level to melt. + keep_index : boolean, optional, default False + If True, the original index is reused. + In the resulting MulitIndex the names of the unpivoted columns + are added as an additional level to ensure uniqueness. See also -------- @@ -4439,11 +4443,11 @@ def unstack(self, level=-1, fill_value=None): versionadded='.. versionadded:: 0.20.0\n', other='melt')) def melt(self, id_vars=None, value_vars=None, var_name=None, - value_name='value', col_level=None): + value_name='value', col_level=None, keep_index=False): from pandas.core.reshape.reshape import melt return melt(self, id_vars=id_vars, value_vars=value_vars, var_name=var_name, value_name=value_name, - col_level=col_level) + col_level=col_level, keep_index=keep_index) # ---------------------------------------------------------------------- # Time series-related diff --git a/pandas/core/reshape/reshape.py b/pandas/core/reshape/reshape.py index b4abba8026b35..6a10fd218287b 100644 --- a/pandas/core/reshape/reshape.py +++ b/pandas/core/reshape/reshape.py @@ -720,8 +720,7 @@ def _convert_level_number(level_num, columns): versionadded="", other='DataFrame.melt')) def melt(frame, id_vars=None, value_vars=None, var_name=None, - value_name='value', col_level=None): - # TODO: what about the existing index? + value_name='value', col_level=None, keep_index=False): if id_vars is not None: if not is_list_like(id_vars): id_vars = [id_vars] @@ -779,7 +778,22 @@ def melt(frame, id_vars=None, value_vars=None, var_name=None, mdata[col] = np.asanyarray(frame.columns ._get_level_values(i)).repeat(N) - return DataFrame(mdata, columns=mcolumns) + result = DataFrame(mdata, columns=mcolumns) + + if keep_index: + orig_index_values = list(np.tile(frame.index.get_values(), K)) + + if len(frame.index.names) == len(set(frame.index.names)): + orig_index_names = frame.index.names + else: + orig_index_names = ["original_index_{i}".format(i=i) + for i in range(len(frame.index.names))] + + result[orig_index_names] = DataFrame(orig_index_values) + + result = result.set_index(orig_index_names + list(var_name)) + + return result def lreshape(data, groups, dropna=True, label=None):