【问题标题】:Missing rows when adding a series as a new column to a pandas dataframe将系列作为新列添加到熊猫数据框时缺少行
【发布时间】:2021-04-29 14:48:08
【问题描述】:

我有两个系列,s1 和 s2,通过以下方式定义:

s1 = pd.Series({1: 10, 2: 20, 3: 30, 4: 40}, name='s1')
s2 = pd.Series({3: 35, 4: 45, 5: 55, 6: 65}, name='s2')

它们看起来像这样:

1    10
2    20
3    30
4    40
Name: s1, dtype: int64

3    35
4    45
5    55
6    65
Name: s2, dtype: int64

我正在尝试创建一个数据框,它将 s1 和 s2 作为两列,索引是两个系列索引的组合。但是一个简单的分配是行不通的:

df = pd.DataFrame()
df['s1'] = s1
df['s2'] = s2

生成的数据帧具有来自 s1 的索引,但错过了 s2 中索引不在 s1 中的行:

   s1    s2
1  10   NaN
2  20   NaN
3  30  35.0
4  40  45.0

这是为什么呢?这似乎有点违反直觉。

注意 - 建议的解决方案是:

df = pd.concat((s1, s2), axis=1)

给出了预期的结果:

     s1    s2
1  10.0   NaN
2  20.0   NaN
3  30.0  35.0
4  40.0  45.0
5   NaN  55.0
6   NaN  65.0

但我仍然很好奇为什么简单的列分配不起作用。

【问题讨论】:

    标签: python pandas dataframe series


    【解决方案1】:

    因为它在索引上匹配,而 s2 从 3 开始

    
    df = pd.DataFrame()
    df['s1'] = s1
    df['s2'] = s2
    
    

    这是根据 s1 设置形状,然后将 s2 数据匹配到 s1 df 形状。

    
    df with s1
       s1
    1  10
    2  20
    3  30
    4  40
    
    df with s2
       s2
    3  35
    4  45
    5  55
    6  65
    
    

    【讨论】:

      【解决方案2】:

      这是因为在将 Series 分配给空数据框的列后,创建的数据框索引与 Series 对齐。

      然后将另一个系列分配给单列数据框的新列,只考虑数据框中的索引。

      如果您尝试在s1 之前分配s2

         s2    s1
      3  35  30.0
      4  45  40.0
      5  55   NaN
      6  65   NaN
      
      print(df)
      
         s2    s1
      3  35  30.0
      4  45  40.0
      5  55   NaN
      6  65   NaN
      

      【讨论】:

        【解决方案3】:

        由于 2 个系列具有不同的索引,因此将任一系列(无论是 s1 在 s2 之前还是 s2 在 s1 之前)分配给空数据框仍然会导致您丢失行。这是因为空数据帧的数据帧索引会自动设置为分配给它的第一个系列的索引。因此,当将第二个系列分配给数据帧时,它将只获取与其当前索引对齐的行(刚刚设置为 s1 的索引),并忽略 s2 索引的其余部分中与 s1 不常见的行。

        有一种补救措施可以使将 s1s2 分配给 df 的 2 个语句按预期工作:

        df = pd.DataFrame(index=s1.index.union(s2.index))
        

        通过将数据帧索引预设为 s1.index 和 s2.index s1.index.union(s2.index) 的并集,你会得到你想要的结果:

        df['s1'] = s1
        df['s2'] = s2
        
        
        print(df)
        
             s1    s2
        1  10.0   NaN
        2  20.0   NaN
        3  30.0  35.0
        4  40.0  45.0
        5   NaN  55.0
        6   NaN  65.0
        

        分解中间步骤,你会看到有趣的结果:

        df = pd.DataFrame(index=s1.index.union(s2.index))
        df['s1'] = s1
        
        
        print(df)
        
             s1
        1  10.0
        2  20.0
        3  30.0
        4  40.0
        5   NaN
        6   NaN   
        

        在这里,在分配 s2 之前,在仅分配 s1 和分配 s2 之前,您仍然可以看到索引 5 6(仅是 s2 的一部分)。索引5 6 的对应值为NaN。这是因为我们已经定义了空数据框df,索引是 s1 和 s2 的并集,而 s2 尚未分配给它。

        如果您只想在 s1 分配给未使用index= 参数设置的空数据帧后即时修改数据帧索引,您可以通过df.reindex() 进行,如下所示:

        df = pd.DataFrame()                            # without the index= parameter
        df['s1'] = s1
        df = df.reindex(s1.index.union(s2.index))      # Use reindex()
        
        
        
        print(df)
        
             s1    s2
        1  10.0   NaN
        2  20.0   NaN
        3  30.0  35.0
        4  40.0  45.0
        5   NaN  55.0
        6   NaN  65.0
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-01-02
          • 2016-08-24
          相关资源
          最近更新 更多