【问题标题】:Merge a filling DataFrame into a mask, based on index and columns根据索引和列将填充 DataFrame 合并到掩码中
【发布时间】:2021-12-13 20:27:45
【问题描述】:

使用以下“掩码”DataFrame:

>>> mask
               city      value_1      value_2
index
0            London           10          NaN
1             Paris          NaN           21
2             Paris           30          NaN
3             Paris          NaN          NaN
4            Berlin            3            5
5            Berlin          NaN           10
6          New York          NaN          NaN

以及下面的“填充”框架:

>>> filling
                value_1      value_2
London             1100         2100
Paris              1150         2200
Berlin              NaN         3000
New York           5000          NaN

如何根据city AND 列将filling 合并到mask 中,从而使生成的DataFrame 变为:

>>> result
               city      value_1      value_2
index
0            London           10         2100
1             Paris         1150           21
2             Paris           30         2200
3             Paris         1150         2200
4            Berlin            3            5
5            Berlin          NaN           10
6          New York         5000          NaN

从概念上讲,mask 中的任何值(即NaN)都容易被filling 的值“填充”,该值匹配其city 及其列(value_1value_2)。

我正在努力解决的部分是让DataFrame.merge() 同时考虑索引(此处为city)和所有列。两者都可以,但要获得预期的结果,我似乎需要两者。

编辑:

我尝试了以下方法:

>>> expanded = mask[[]].join(filling, on='city')
>>> mask.merge(expanded)

但这只会让我返回mask,并且来自expanded 的所有值都被简单地忽略(即使目标单元格是NaN)。

【问题讨论】:

    标签: python pandas dataframe join merge


    【解决方案1】:

    您也可以使用专为此目的设计的combine_first

    print (mask.set_index("city").combine_first(filling))
    
              value_1  value_2
    Berlin        3.0      5.0
    Berlin        NaN     10.0
    London       10.0   2100.0
    New York   5000.0      NaN
    Paris      1150.0     21.0
    Paris        30.0   2200.0
    Paris      1150.0   2200.0
    

    如果您需要保留原始订单,请先执行reset_index,然后再对其进行排序。

    【讨论】:

      【解决方案2】:

      为此,我们可以使用DataFrame.updateoverwrite=False

      注意:我们将方法分隔在不同的行中,因为更新是就地的。

      mask = mask.set_index("city")
      mask.update(filling, overwrite=False)
      mask = mask.reset_index()
      
             city  value_1  value_2
      0    London     10.0   2100.0
      1     Paris   1150.0     21.0
      2     Paris     30.0   2200.0
      3     Paris   1150.0   2200.0
      4    Berlin      3.0      5.0
      5    Berlin      NaN     10.0
      6  New York   5000.0      NaN
      

      【讨论】:

      • OP 不想更新已经存在的值。
      • 同意,进行了相应的修改。
      • 也是非常好的解决方案——我接受了另一个,因为它没有更新mask,而是返回一个新的DataFrame,它更符合我的需要,但我会请记住这一点,谢谢。
      【解决方案3】:

      试试fillnareindexfilling

      mask.fillna(filling.reindex(mask.city).set_index(mask.index))
      

      输出:

                 city  value_1  value_2
      index                            
      0        London     10.0   2100.0
      1         Paris   1150.0     21.0
      2         Paris     30.0   2200.0
      3         Paris   1150.0   2200.0
      4        Berlin      3.0      5.0
      5        Berlin      NaN     10.0
      6      New York   5000.0      NaN
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-27
        • 1970-01-01
        • 2014-09-25
        • 2022-01-12
        • 2017-01-09
        • 2021-10-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多