【问题标题】:Update dataframe according to another dataframe based on certain conditions根据某些条件根据另一个数据帧更新数据帧
【发布时间】:2017-06-09 21:44:16
【问题描述】:

我有两个数据框 df1df2。 Df1 具有 A、B、C、D、E、F 列和 df2 A、B、J、D、E、K 列。我想用第一个数据帧的行更新第二个数据帧,但只有当两个第一列在两个数据帧中具有相同的值时。对于满足以下两个条件的每一行:

  1. df1.A = df2.A
  2. df1.B = df2.B

然后相应地更新:

df2.D = df1.D  
df2.E = df1.E

我的数据框有不同的行数。

当我尝试这段代码时,我得到一个 TypeError :cannot do position indexing with these indexers of type 'str'.

for a in df1:
    for t in df2:
        if df1.iloc[a]['A'] == df2.iloc[t]['A'] and df1.iloc[a]['B'] == df2.iloc[t]['B']:
            df2.iloc[t]['D'] = df1.iloc[a]['D']
            df2.iloc[t]['E'] = df1.iloc[a]['E']

【问题讨论】:

  • 请包括样本输入数据和预期输出。见:stackoverflow.com/a/20159305/3339965
  • 如果您的数据框有不同的行数,您希望如何将一列与另一列进行比较?

标签: python pandas dataframe


【解决方案1】:

问题:

与进行嵌套迭代相比,合并数据帧会更好。

df2 = df2.merge(df1[['A', 'B', 'D', 'E']], on=['A', 'B'], how='left', suffixes=['_old', ''])
df2['D'] = df2['D'].fillna(df2['D_old'])
df2['E'] = df2['E'].fillna(df2['E_old'])
del df2['D_old']
del df2['E_old']

第一行将列附加到df2,列DE 的值来自df1 的对应行,并重命名旧列。 接下来的两行填充了df1 没有匹配行的行,接下来的两行删除了最初的、现在已经过时的列版本。

错误:

您的TypeError 发生是因为for a in df1: 迭代数据帧的列,这里是字符串,而.iloc 只接受整数。此外,虽然您还没有达到这一点,但要设置一个值,您需要在括号内同时包含索引和列。

所以如果你确实需要按行设置值,你会想要更像

for a in df1.iterrows():
    for t in df2.iterrows():
        if df1.loc[a, 'A'] == ...

虽然我强烈反对这样做。如果您发现自己正在考虑它,可能有一种更快、更不痛苦的方式在 pandas 中执行此操作,或者您最好使用另一种不太关注表格数据的工具。

【讨论】:

  • 感谢您的回答。您的代码非常清晰。问题是,即使对于 df1.A=df2.A 和 df1.B=df2.B 的相应行,合并数据帧后,C 列和 D 列仍然仅填充 NaN 值。因此,在执行下一行以填充空值后,我最终得到了与合并之前相同的数据帧。
  • @whateveros 您能否按照@root 的要求进行编辑以包含示例数据?这对我有用。作为猜测,您确定 df1 和 df2 的值相等吗?如果连接键上根本没有匹配项,您将得到您描述的结果。请注意,这可能是由于精度或类型差异造成的。
  • 我现在无法进行编辑,但我针对我创建的一组不同的数据框测试了您的解决方案,并且工作正常。所以我刚刚检查了我在 df1 和 df2 上的列的 dtypes,它完全匹配。我也有很多 A 和 B 列的匹配值,所以我想弄清楚为什么它只给我空值。
  • 如果你从 df1 中取出一些应该匹配的行并将 df2 过滤到带有df2[(df2['A'] == df1.loc[row_index, 'A']) & (df2['B'] == df1.loc[row_index, 'B'])] 的那些值,会发生什么?你有没有返回任何行,或者只是一个空的数据框?
  • 我实际上通过转换我在(A 和 B)上进行左连接的列的类型来解决我的问题。它是“O”,我将它们转换为字符串。您的代码现在运行完美。谢谢@EFT!
猜你喜欢
  • 2022-01-24
  • 1970-01-01
  • 1970-01-01
  • 2021-10-10
  • 1970-01-01
  • 1970-01-01
  • 2017-11-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多