Assign value based on lookup dictionary in a multilevel column Pandas

The objective is to assign value to column Group based on the comparison between the value in column my_ch and look-up dict dict_map

The dict_map is define as

dict_map=dict(group_one=['B','D','GG','G'],group_two=['A','C','E','F'])

Whereas the df is as below

first  my_ch       bar            ...       foo       qux          
second             one       two  ...       two       one       two
0          A  0.037718  0.089609  ...  0.202885  0.706059 -2.280754
1          B  0.578452  0.039445  ... -0.153135  0.178715 -0.040345
2          C  2.139270  1.104547  ...  0.989953 -0.280724 -0.739488
3          D  0.733355  0.227912  ... -1.359441  0.761619 -1.119464
4          G -1.565185 -1.070280  ...  0.458847  1.072471  1.724417

This comparison should produce the output as below

first  Group my_ch       bar            ...       foo       qux          
second             one       two  ...       two       one       two
0    group_two    A  0.037718  0.089609  ...  0.202885  0.706059 -2.280754
1    group_one    B  0.578452  0.039445  ... -0.153135  0.178715 -0.040345
2    group_two    C  2.139270  1.104547  ...  0.989953 -0.280724 -0.739488
3    group_one    D  0.733355  0.227912  ... -1.359441  0.761619 -1.119464
4    group_one    G -1.565185 -1.070280  ...  0.458847  1.072471  1.724417

My impression, this can be simply achieved via the line

df[('Group', slice ( None ))]=df.loc [:, ('my_ch', slice ( None ))].apply(lambda x: dict_map.get(x))

However, the compiler return an error of

TypeError: unhashable type: 'Series'

Im thinking of converting the series into Dataframe type to bypass this issue, but I wonder there is more reasonable way of solving this issue.

The full code to reproduce the above error is

import pandas as pd
import numpy as np
dict_map=dict(group_one=['B','D','GG','G'],group_two=['A','C','E','F'])
arrays = [["bar", "bar", "baz", "baz", "foo", "foo", "qux", "qux"],
          ["one", "two", "one", "two", "one", "two", "one", "two"]]
tuples = list(zip(*arrays))

index = pd.MultiIndex.from_tuples(tuples, names=["first", "second"])
df = pd.DataFrame(np.random.randn(5, 8), index=["A", "B", "C","D",'G'], columns=index)
df = df.rename_axis ( index=['my_ch'] ).reset_index()
df[('Group', slice ( None ))]=df.loc [:, ('my_ch', slice ( None ))].apply(lambda x: dict_map.get(x))

Edit:

df['Group']=df['my_ch'].apply(lambda x: dict_map.get(x))

Produced Group of None

first  my_ch       bar                 baz  ...       foo       qux           Group
second             one       two       one  ...       two       one       two      
0          A  1.220946  0.714748  0.053371  ... -1.743287  0.400862 -1.066441  None
1          B  0.606736  0.844995  0.579328  ... -0.472185  1.102245  0.454315  None
2          C  1.666148 -0.333102  1.950425  ... -0.021484  3.178110 -0.176937  None
3          D -0.673474  2.263407 -0.074996  ... -0.605594  1.410987 -1.253847  None
4          G  0.652557  2.271662 -0.569529  ... -0.549246 -0.021359 -0.532386  None

Answer

Slice the my_ch using df.xs column and then map after reversing the dict:

d = {i:k for k,v in dict_map.items() for i in v}
out = df.assign(Group=df.xs("my_ch",axis=1).map(d))