

PandasのDataFrameを、unstackしたいのですが、  
エラー「ValueError: Index contains duplicate entries, cannot reshape」が発生し困っています。  
エラーメッセージより、unstackするDataFrameは、unstack後のインデックスがユニークでないといけないようなのです。  
以下のような、データ変換をしたいのですが、どのようにすればよいか、教えていただけないでしょうか。

[code]

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame(
        data=[
            [10, 100],
            [20, 200],
            [30, 300],
            [40, 400],
        ],
        index=[
            ['埼玉', '埼玉', '東京', '東京'],
            ['タイプA', 'タイプB', 'タイプC', 'タイプC'],  # ←キーが重複しているとエラーが発生しunstackできないようです。
            # ['タイプA', 'タイプB', 'タイプB', 'タイプC'],  # ←正しくunstackできました。
        ],
        columns=[
            ['値１', '値２'],
        ]
    )
    print('【入力】')
    display(df)
    
    df = df.unstack(level=0)
    df = df.swaplevel(axis='columns').sort_index(axis='columns')
    display(df)
    
[/code]

[![画像の説明をここに入力](https://i.stack.imgur.com/0RW49.png)](https://i.stack.imgur.com/0RW49.png)

エラーメッセージ

[code]

    ---------------------------------------------------------------------------
    ValueError                                Traceback (most recent call last)
    Cell In[2], line 30
         27 print('【入力】')
         28 display(df)
    ---> 30 df = df.unstack(level=0)
         31 df = df.swaplevel(axis='columns').sort_index(axis='columns')
         32 display(df)
    
    File ~/workspace/orcas_proj/venv/lib/python3.8/site-packages/pandas/core/frame.py:8961, in DataFrame.unstack(self, level, fill_value)
       8899 """
       8900 Pivot a level of the (necessarily hierarchical) index labels.
       8901 
       (...)
       8957 dtype: float64
       8958 """
       8959 from pandas.core.reshape.reshape import unstack
    -> 8961 result = unstack(self, level, fill_value)
       8963 return result.__finalize__(self, method="unstack")
    
    File ~/workspace/orcas_proj/venv/lib/python3.8/site-packages/pandas/core/reshape/reshape.py:475, in unstack(obj, level, fill_value)
        473 if isinstance(obj, DataFrame):
        474     if isinstance(obj.index, MultiIndex):
    --> 475         return _unstack_frame(obj, level, fill_value=fill_value)
        476     else:
        477         return obj.T.stack(dropna=False)
    
    File ~/workspace/orcas_proj/venv/lib/python3.8/site-packages/pandas/core/reshape/reshape.py:498, in _unstack_frame(obj, level, fill_value)
        496 def _unstack_frame(obj: DataFrame, level, fill_value=None):
        497     assert isinstance(obj.index, MultiIndex)  # checked by caller
    --> 498     unstacker = _Unstacker(obj.index, level=level, constructor=obj._constructor)
        500     if not obj._can_fast_transpose:
        501         mgr = obj._mgr.unstack(unstacker, fill_value=fill_value)
    
    File ~/workspace/orcas_proj/venv/lib/python3.8/site-packages/pandas/core/reshape/reshape.py:136, in _Unstacker.__init__(self, index, level, constructor)
        128 if num_cells > np.iinfo(np.int32).max:
        129     warnings.warn(
        130         f"The following operation may generate {num_cells} cells "
        131         f"in the resulting pandas object.",
        132         PerformanceWarning,
        133         stacklevel=find_stack_level(),
        134     )
    --> 136 self._make_selectors()
    
    File ~/workspace/orcas_proj/venv/lib/python3.8/site-packages/pandas/core/reshape/reshape.py:188, in _Unstacker._make_selectors(self)
        185 mask.put(selector, True)
        187 if mask.sum() < len(self.index):
    --> 188     raise ValueError("Index contains duplicate entries, cannot reshape")
        190 self.group_index = comp_index
        191 self.mask = mask
    
    ValueError: Index contains duplicate entries, cannot reshape
    
[/code]

以下は、期待する結果です。

[code]

    # 期待する結果
    df = pd.DataFrame(
        data=[
            [np.nan, np.nan, 10, 100],
            [np.nan, np.nan, 20, 200],
            [30, 300, np.nan, np.nan],
            [40, 400, np.nan, np.nan],
        ],
        index=['タイプA', 'タイプB', 'タイプC', 'タイプC'],
        columns=[
            ['埼玉', '埼玉', '東京', '東京'],
            ['値１', '値２', '値１', '値２'],
        ]
    )
    print('【期待する結果】')
    display(df)
    
[/code]

[![画像の説明をここに入力](https://i.stack.imgur.com/EdnTd.png)](https://i.stack.imgur.com/EdnTd.png)


CC BY-SA 4.0
2023-05-30T10:32:34.000
95024
2023-07-15T11:35:12.170
2023-07-15T11:35:12.170
3060
35267
question
python python3 pandas
キーがユニークでないDataFrameをunstackする方法

[code]

    df = df.T.groupby(df.index, axis=1).sum().T
    df.index = pd.MultiIndex.from_tuples(df.index)
    
    df = df.unstack(level=0)
    df = df.swaplevel(axis='columns').sort_index(axis='columns')
    
    #          埼玉         東京       
    #          値１   値２   値１    値２
    # タイプA  10.0  100.0   NaN    NaN
    # タイプB  20.0  200.0   NaN    NaN
    # タイプC   NaN    NaN  70.0  700.0
    
[/code]


CC BY-SA 4.0
2023-05-30T11:34:26.150
95025
2023-05-30T11:34:26.150
47127
95024
answer