【问题标题】:Replace zeros in one dataframe with values from another dataframe用另一个数据帧中的值替换一个数据帧中的零
【发布时间】:2018-01-23 21:17:32
【问题描述】:

我有两个数据框 df1 和 df2: df1 显示在这里:

   age
0   42
1   52
2   36
3   24
4   73

df2 显示在这里:

   age
0    0
1    0
2    1
3    0
4    0

我想用 df1 中的相应条目替换 df2 中的所有零。用更专业的话说,如果 df2 中某个索引处的元素为零,那么我希望这个元素被 df1 中的相应条目替换。

因此,我希望 df2 看起来像:

   age
0    42
1    52
2    1
3    24
4    73

我尝试使用替换方法,但它不起作用。请帮忙 :) 提前致谢。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    你可以使用where:

    In [19]: df2.where(df2 != 0, df1)
    Out[19]: 
       age
    0   42
    1   52
    2    1
    3   24
    4   73
    

    在上面,df2 != 0 是一个布尔数据框。

    In [16]: df2 != 0
    Out[16]: 
         age
    0  False
    1  False
    2   True
    3  False
    4  False
    

    df2.where(df2 != 0, df1) 返回一个新的 DataFrame。其中df2 != 0 为True,则使用df2 的对应值。如果为 False,则使用 df1 的对应值。


    另一种选择是使用df.loc 进行分配:

    df2.loc[df2['age'] == 0, 'age'] = df1['age']
    

    df.loc[mask, col] 选择 df 的行,其中布尔系列 mask 为 True,列标签为 col

    In [17]: df2.loc[df2['age'] == 0, 'age']
    Out[17]: 
    0    0
    1    0
    3    0
    4    0
    Name: age, dtype: int64
    

    在作业中使用时,例如df2.loc[df2['age'] == 0, 'age'] = df1['age'], Pandas 执行自动索引标签对齐。 (注意上面的索引标签是 0,1,3,4 - 2 被跳过)。所以df2.loc[df2['age'] == 0, 'age'] 中的值被d1['age'] 中的对应值替换。即使d1['age'] 是一个带有索引标签01234 的系列,2 也会被忽略,因为左侧没有相应的索引标签一边。

    换句话说,

    df2.loc[df2['age'] == 0, 'age'] = df1.loc[df2['age'] == 0, 'age']
    

    也可以,但不需要在右侧添加限制。

    【讨论】:

    • 谢谢。但是,当我尝试 df2.where(df2['age'] != 0, df1) 我得到 AttributeError: 'float' object has no attribute 'all'
    • 我认为你遇到了this bug——你可以通过升级你的熊猫版本来修复它。
    • 熊猫版本无法更改,因为它安装在服务器上,我只能使用那个:(我拥有的熊猫版本是0.15.1'
    • 那我相信你可以改用df2.loc[df2['age'] == 0, 'age'] = df1['age']
    • 非常感谢,效果很好! :) 你能解释一下这段代码是如何工作的吗?甚至 df2.where(df2 != 0, df1) 的工作原理
    【解决方案2】:
    In [30]: df2.mask(df2==0).combine_first(df1)
    Out[30]:
        age
    0  42.0
    1  52.0
    2   1.0
    3  24.0
    4  73.0
    

    或“否定”beautiful @unutbu's solution:

    In [46]: df2.mask(df2==0, df1)
    Out[46]:
       age
    0   42
    1   52
    2    1
    3   24
    4   73
    

    【讨论】:

    • @Vaishali,是的,谢谢!这是对美丽 unutbu 解决方案的“否定”:)
    【解决方案3】:

    或者试试mul

    df1.mul(np.where(df2==1,0,1)).replace({0:1})
    

    【讨论】:

      猜你喜欢
      • 2015-12-19
      • 2016-07-24
      • 1970-01-01
      • 2019-08-06
      • 1970-01-01
      • 2016-11-17
      • 1970-01-01
      • 1970-01-01
      • 2021-08-02
      相关资源
      最近更新 更多