【问题标题】:Replace values in one dataframe with values in second dataframe in Python用 Python 中的第二个数据帧中的值替换一个数据帧中的值
【发布时间】:2016-03-24 05:24:14
【问题描述】:

我有一个大型数据框 (DF1),其中包含一个包含英国邮政编码数据的变量。数据中难免有一些错别字。然而,在对正则表达式进行了一些工作之后,我创建了第二个数据库,其中包含邮政编码数据的更正版本(但仅适用于原始邮政编码不正确的那些行)——DF2。 (注意,索引值不一定是连续的。)

    id   postcode                     remark
0    1      L93AP                     Normal
2    2     LD38AH                     Normal
4    3    SO224ER                     Normal
6    4       SO21                  Too short
8    5    DN379HJ                     Normal
10   6     M21ORH  Zero replaced with O (oh)
12   7     NP745G          S replaced with 5
14   8    SE136R2          Z replaced with 2
16   9  BN251ESBN                   Too long
18  10    TD152EH                     Normal

包含更正数据的数据框是:

       0  1  2  3 pcCorrected
10   M21  0  R  H      M210RH
12   NP7  4  S  G      NP74SG
14  SE13  6  R  Z     SE136RZ

我想合并 2 个数据库,以便 DF2 中 pcCorrected 列中的新值替换 DF1 数据框中的旧邮政编码值,但对于其他单元格,现有邮政编码值保持不变。最终的数据库应如下所示:

    id   postcode                     remark
0    1      L93AP                     Normal
2    2     LD38AH                     Normal
4    3    SO224ER                     Normal
6    4       SO21                  Too short
8    5    DN379HJ                     Normal
10   6     M210RH                     Normal
12   7     NP74SG                     Normal
14   8    SE136RZ                     Normal
16   9  BN251ESBN                   Too long
18  10    TD152EH                     Normal

数据库非常大(>100 万行)。此操作是否有名称?最有效的方法是什么?

【问题讨论】:

    标签: python python-3.x pandas dataframe


    【解决方案1】:

    您可以通过 indexes 尝试 merge ,通过 notnull 创建 mask 并通过 loc 添加新值:

    df = pd.merge(df1, df2, left_index=True, right_index=True, how='left')
    mask = pd.notnull(df['pcCorrected'])
    print mask
    0     False
    2     False
    4     False
    6     False
    8     False
    10     True
    12     True
    14     True
    16    False
    18    False
    Name: pcCorrected, dtype: bool
    
    df.loc[mask, 'remark'] = 'Normal'
    df.loc[mask, 'postcode'] = df['pcCorrected']
    
    print df[['id','postcode','remark']]
        id   postcode     remark
    0    1      L93AP     Normal
    2    2     LD38AH     Normal
    4    3    SO224ER     Normal
    6    4       SO21  Too short
    8    5    DN379HJ     Normal
    10   6     M210RH     Normal
    12   7     NP74SG     Normal
    14   8    SE136RZ     Normal
    16   9  BN251ESBN   Too long
    18  10    TD152EH     Normal
    

    【讨论】:

    • 当我第一次阅读这个答案时,我有点担心如果修改了数据帧,基于掩码将一列从一个 df 添加到另一个可能会不同步。但是,在重新阅读时,我可以看到这个解决方案比这更微妙和安全。合并到单个 df 中,然后在新创建的 df 中操作列,从而解决所有这些问题。简而言之,我真的很喜欢这个答案。非常感谢。
    • 从内存管理的角度来看,将 DF2 合并到 DF1 会更好吗?使用 DF1 = DF1.merge(DF2, left_index=True, right_index=True, how='left') - 而不是创建另一个全新的(大型)数据框?
    • 我认为最好使用现有的DF2。最好是测试一下。
    【解决方案2】:

    也许更简单的方法是:

    掩码 = df1.index.isin(df2.index)

    df1.loc[mask,'postcode'] = df2['pcCorrected']

    这样可以避免合并两个 DataFrame 的额外步骤

    【讨论】:

    • 要使用indexdf1df2必须排序。是否可以避免排序并使用其中一列,例如在这种情况下id 列?
    【解决方案3】:

    一种方法是遍历包含校正值的数据帧的每一行,然后转移到原始数据帧:

    for i in DF2.index:
        DF1.ix[i,'postcode'] = DF2.ix[i,'pcCorrected']
    

    有没有更有效的方法来做到这一点?

    【讨论】:

    • 这里使用的ix 是什么?
    【解决方案4】:

    您可以按照以下步骤将第一个数据帧df1 的值替换为第二个数据帧df2 的值。

    第一步:设置第一个数据帧的索引(df1)

    df1.set_index('id')
    

    第 2 步:设置第二个数据帧的索引 (df2)

    df2.set_index('id')
    

    最后使用下面的 sn-p 更新数据框——

    df1.update(df2)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-29
      • 2016-07-24
      • 2020-05-26
      • 2018-01-23
      • 1970-01-01
      • 2016-11-17
      • 1970-01-01
      • 2020-06-22
      相关资源
      最近更新 更多