【问题标题】:Pandas DataFrame apply or map dictionary valueassign column to function of MultiIndex valuePandas DataFrame 将字典 valueassign 列应用或映射到 MultiIndex 值的函数
【发布时间】:2024-01-14 14:15:01
【问题描述】:

我想(通过字典)将 MultiIndex DataFrame 的一部分映射到列。有没有办法一步完成?

例如,使用以下示例 DataFrame:

i = pd.MultiIndex.from_product([['A','B','C'], np.arange(1, 11, 1)], names=['Name','Num'])
df = pd.DataFrame(np.random.randn(30), i, columns=['Vals'])

和示例地图:

a = list('abcdefghijk')
m = {}
for i in range(0,11):
    m[i] = a[i]

我想创建一个 X 列,其中包含与第二个索引级别关联的字母:

df.assign(X=m[df.index.get_level_values('Num').values])

但这不起作用,也不起作用:

df['X'] = df.index.map(lambda x: m[x[1]])

【问题讨论】:

    标签: python pandas dictionary dataframe multi-index


    【解决方案1】:

    使用get_level_values 访问第二层,转换为Series,然后调用map/replace -

    df['X'] = df.index.get_level_values(1).to_series().map(m).values
    

    或者,

    df['X'] = df.index.get_level_values(1).to_series().replace(m).values
    

    或者(受 OP 启发),您可以在 df.index.get_level_values 上调用 map,并传递一个可调用对象(在本例中为 m.get)-

    df['X'] = df.index.get_level_values(1).map(m.get)
    

    df
    
                  Vals  X
    Name Num             
    A    1    2.731237  b
         2    0.180595  c
         3   -1.428064  d
         4   -0.622806  e
         5    0.948709  f
         6   -1.383310  g
         7    0.177631  h
         8   -1.071445  i
         9   -0.183859  j
         10   1.480641  k
    B    1   -1.036380  b
         2    1.031757  c
         3    0.542989  d
         4   -0.933676  e
         5   -0.540661  f
         6   -0.506969  g
         7    0.572705  h
         8   -1.363675  i
         9   -0.588765  j
         10   0.998691  k
    C    1   -0.471536  b
         2   -1.361124  c
         3   -0.382200  d
         4    0.694174  e
         5    1.077779  f
         6   -0.501285  g
         7    0.961986  h
         8   -0.285009  i
         9    1.385881  j
         10   1.490152  k
    

    在这里,我必须致电.values,因为我希望能够将结果分配回数据框而不会出现索引对齐问题。

    【讨论】:

      【解决方案2】:

      这是另一个有效的速记:

      df['X'] = df.index.map(lambda x: m.get(x[1]))
      

      在这样的 lambda 中使用字典并不是无效的,只是(显然)字典值的索引表示法(例如,m[x[1]])查找在这种情况下不起作用。

      【讨论】:

      • 感谢您的回答,我能够为我找到一个更短的变体:df.index.get_level_values(1).map(m.get)
      【解决方案3】:

      rename 然后将其分配回去

      df['New']=df.rename(index=m,level=1).index.get_level_values(1)
      df
      Out[132]: 
                    Vals New
      Name Num              
      A    1   -0.906266   b
           2    0.321047   c
           3    0.227720   d
           4    3.040522   e
           5    0.604392   f
           6    1.394153   g
           7   -0.640342   h
           8   -0.812858   i
           9   -1.142764   j
           10   0.744968   k
      B    1    0.956003   b
           2    0.064266   c
           3    0.042286   d
           4   -1.089578   e
           5    0.534922   f
           6   -0.545524   g
           7    0.102778   h
           8   -1.691460   i
           9   -1.980935   j
           10   1.226609   k
      C    1    0.871654   b
           2    0.396818   c
           3    0.691537   d
           4    1.923429   e
           5    0.239363   f
           6   -0.669168   g
           7   -0.168082   h
           8    0.209918   i
           9    0.205527   j
           10   0.490754   k
      

      【讨论】:

        最近更新 更多