Python-pandasの階層型インデックスにおいて、親子関係を保ったまま親をシャッフルすることはできるのでしょうか。


**\- 環境**  
Mac  
Python 3.7.3  
Jupyter Notebook 5.7.8

**\- やりたいこと**  
親ID列・子ID列を持ったデータフレームがあります。  
このとき、全行を単純にランダムソートするのではなく、同じ親IDを持つ行をグループ化した上で、そのグループをランダムソートできるでしょうか。

**\- やったこと**  
一部の抽出対象のparent-idが格納された配列を用意。  
isinメソッドでマッチしたデータを出力しようとしましたが、parent-
idをひとかたまりにランダム出力されるのではなく、単純なランダムソートで出力されてしまいます。

Python Code

[code]

    lis = [2, 3, 1] #parent-idが1~3までのものが出力対象
    test_df = pd.DataFrame({"parent-id": [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4],
                            "child-id": [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]})
    
    f = lambda x: x[(x["parent-id"].isin(lis))]
    test_df.groupby(["parent-id"]).apply(f).sample(frac=1, random_state=0)
    
[/code]

[![出力結果](https://i.stack.imgur.com/BW0g0.png)](https://i.stack.imgur.com/BW0g0.png)




結論、user10685さんに記載いただいた内容を参考にして、groupbyを意識したことにより、以下のtipsで解決いたしました。  
[Shuffle a pandas dataframe by
groups](https://stackoverflow.com/questions/45585860/shuffle-a-pandas-
dataframe-by-groups)

fixしたコードは以下です。

[code]

    lis = [2, 3, 1]
    test_df = pd.DataFrame({"parent-id": [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4],
                            "child-id": [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]})
    groups = [test_df for _, test_df in test_df[(test_df["parent-id"].isin(lis))].groupby('parent-id')]
    random.shuffle(groups)
    pd.concat(groups).reset_index(drop=True)
    
[/code]

[![親単位でのグループシャッフル](https://i.stack.imgur.com/HyXD2.png)](https://i.stack.imgur.com/HyXD2.png)




結論、user10685さんに記載いただいた内容を参考にして、groupbyを意識したことにより、以下のtipsで解決いたしました。  
[Shuffle a pandas dataframe by
groups](https://stackoverflow.com/questions/45585860/shuffle-a-pandas-
dataframe-by-groups)

fixしたコードは以下です。

[code]

    lis = [2, 3, 1]
    test_df = pd.DataFrame({"parent-id": [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4],
                            "child-id": [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]})
    groups = [test_df for _, test_df in test_df[(test_df["parent-id"].isin(lis))].groupby('parent-id')]
    random.shuffle(groups)
    pd.concat(groups).reset_index(drop=True)
    
[/code]

[![親単位でのグループシャッフル](https://i.stack.imgur.com/HyXD2.png)](https://i.stack.imgur.com/HyXD2.png)

