【问题标题】:Create new column for in multiindex dataframe and fillna在多索引数据框和fillna中创建新列
【发布时间】:2018-12-09 04:47:19
【问题描述】:

假设我有以下多索引数据框,使用以下代码生成:

import pandas as pd, numpy as np

names = ['Name1','Name2','Name3','Name4']
values = ['x1','x2','x3','x4']
categories = ['y1','y2','y3']

x1 = pd.Series([0, 0, 0], index=categories)

index = pd.MultiIndex.from_product([names, values]); placeholders = np.zeros((len(names)*len(values), len(categories)))

df = pd.DataFrame(placeholders, index=index, columns=categories)

for i in names:
    for j in values:
        df.loc[i,j] = x1

           y1   y2   y3
Name1 x1  0.0  0.0  0.0
      x2  0.0  0.0  0.0
      x3  0.0  0.0  0.0
      x4  0.0  0.0  0.0
Name2 x1  0.0  0.0  0.0
      x2  0.0  0.0  0.0
      x3  0.0  0.0  0.0
      x4  0.0  0.0  0.0
Name3 x1  0.0  0.0  0.0
      x2  0.0  0.0  0.0
      x3  0.0  0.0  0.0
      x4  0.0  0.0  0.0
Name4 x1  0.0  0.0  0.0
      x2  0.0  0.0  0.0
      x3  0.0  0.0  0.0
      x4  0.0  0.0  0.0

我将如何使用如下字典填充与行 x1 对应的列 y3 并填充 np.nan 以获取 y3 列中任何其他行的值或给定名称(即Name1、Name2、Name3 等)不是字典中的键?

{'Name1': 54, 'Name3': 50}

预期输出(0 可能是 np.nan):

           y1   y2   y3
Name1 x1  0.0  0.0   54
      x2  0.0  0.0  0.0
      x3  0.0  0.0  0.0
      x4  0.0  0.0  0.0
Name2 x1  0.0  0.0  0.0
      x2  0.0  0.0  0.0
      x3  0.0  0.0  0.0
      x4  0.0  0.0  0.0
Name3 x1  0.0  0.0   50
      x2  0.0  0.0  0.0
      x3  0.0  0.0  0.0
      x4  0.0  0.0  0.0
Name4 x1  0.0  0.0  0.0
      x2  0.0  0.0  0.0
      x3  0.0  0.0  0.0
      x4  0.0  0.0  0.0

【问题讨论】:

    标签: python pandas multi-index


    【解决方案1】:

    惯用的方式大概是使用update

    In [31]: df2 = pd.DataFrame({(k,'x1'): {'y3': v} for k, v in d.items()}).T
    
    In [32]: df2
    Out[32]: 
              y3
    Name1 x1  54
    Name3 x1  50
    
    In [33]: df.update(df2)
    
    In [34]: df
    Out[34]: 
               y1   y2    y3
    Name1 x1  0.0  0.0  54.0
          x2  0.0  0.0   0.0
          x3  0.0  0.0   0.0
          x4  0.0  0.0   0.0
    Name2 x1  0.0  0.0   0.0
          x2  0.0  0.0   0.0
          x3  0.0  0.0   0.0
          x4  0.0  0.0   0.0
    Name3 x1  0.0  0.0  50.0
          x2  0.0  0.0   0.0
          x3  0.0  0.0   0.0
          x4  0.0  0.0   0.0
    Name4 x1  0.0  0.0   0.0
          x2  0.0  0.0   0.0
          x3  0.0  0.0   0.0
          x4  0.0  0.0   0.0
    

    【讨论】:

      【解决方案2】:

      您可以创建更新 df 然后使用 update

      d={'Name1': 54, 'Name3': 50}
      updatedf=pd.DataFrame(data=list(d.values()),columns=['y3'],index=pd.MultiIndex.from_arrays([list(d.keys()),['x1','x1']]))
      df.update(updatedf)
      df
      Out[229]: 
                 y1   y2    y3
      Name1 x1  0.0  0.0  54.0
            x2  0.0  0.0   0.0
            x3  0.0  0.0   0.0
            x4  0.0  0.0   0.0
      Name2 x1  0.0  0.0   0.0
            x2  0.0  0.0   0.0
            x3  0.0  0.0   0.0
            x4  0.0  0.0   0.0
      Name3 x1  0.0  0.0  50.0
            x2  0.0  0.0   0.0
            x3  0.0  0.0   0.0
            x4  0.0  0.0   0.0
      Name4 x1  0.0  0.0   0.0
            x2  0.0  0.0   0.0
            x3  0.0  0.0   0.0
            x4  0.0  0.0   0.0
      

      【讨论】:

        【解决方案3】:

        有很多方法可以做到这一点,一种简单的方法是使用.loc 索引器:

        d = {'Name1': 54, 'Name3': 50}
        
        for i in d.keys():
            df.loc[i,'x1']['y3'] = d[i]
        

        【讨论】:

        • 有没有一种有效的方法可以在没有任何 for 循环的情况下执行此操作(考虑到大型数据帧)?
        • 我认为在这种情况下循环是不可避免的,因为我们必须更新多个索引的值。要么我们单独编写每一行,要么让一个循环来完成这项工作。
        • 数据框本身没有更新,值仍然是NaN
        猜你喜欢
        • 2016-02-05
        • 2021-05-07
        • 2020-08-13
        • 2016-06-16
        • 1970-01-01
        • 2023-03-23
        • 2021-11-06
        • 1970-01-01
        • 2020-11-21
        相关资源
        最近更新 更多