簡體   English   中英

如何查找兩個 DataFrame 中存在但在所選列上具有不同值的行

[英]How to find rows that are present in two DataFrames, but with different values on chosen columns

假設我們有兩個 DataFrame, df1df2具有相同的列:

  | Name | Value1 | Value2      | Name | Value1 | Value2
--------------------------   --------------------------
1 | John |    1   |   2       1 | John |    4   |   2   
--------------------------   --------------------------
2 | Sue  |    1   |   2       2 | Sue  |    1   |   3   
--------------------------   --------------------------
3 | Bob  |    1   |   2       3 | Bob  |    5   |   6

正如我們所看到的,唯一的區別是對於Name為“John”的行,列Value1從 1 更改為 4,對於“Sue”,列Value2從 2 更改為 3,對於“Bob”,兩列都更改了。

我的問題是-為每個此類更改提取對( NameColumn(s) )的最慣用的方法是什么? 即使實際值發生了變化,也無關緊要,只有它們對應的行和列。

我想寫一個行為如下的 function:

updated = check_for_updates(df1, df2)
print(updated)
# [
#   ("John", ("Value1",)),
#   ("Sue", ("Value2",)),
#   ("Bob", ("Value1", "Value2")),
# ]

Pandas 1.1 提供了一種比較數據幀的方法; 您可以使用defaultdict進一步擴展它以適合您的最終結果:

from collections import defaultdict

updated = defaultdict(list)
for key, value in (df1
                   .set_index("Name")
                   .compare(df2.set_index("Name"), keep_shape=True)
                   .stack(0).index):
    updated[key].append(value)

print(updated)

defaultdict(list,
            {'John': ['Value1'],
             'Sue': ['Value2'],
             'Bob': ['Value1', 'Value2']})

我認為,如果您嘗試df1.set_index('Name')df2.set_index('Name') ,就可以做你想做的事。 我的意思是你可以用他們的名字提取

好的,我想通了,我對這個解決方案非常滿意:

df1 = DataFrame(data={"Name": ["John", "Sue", "Bob"], "Value1": [1, 1, 1], "Value2": [2, 2, 2]})
df2 = DataFrame(data={"Name": ["John", "Sue", "Bob"], "Value1": [4, 1, 5], "Value2": [2, 3, 6]})

def check_for_updates(df1, df2, columns, index):
  result = df2[df1[columns] != df2[columns]].dropna(how="all") # unchanged rows do not interest me
  result[index] = df1[index]

  return [(_id, tuple(cols.dropna().index)) for _id, cols in result.set_index(index).iterrows()]

updated = check_for_updates(df1, df2, columns=["Value1", "Value2"], index="Name")
print(updated)
# [
#   ('John', ('Value1',)),
#   ('Sue', ('Value2',)),
#   ('Bob', ('Value1', 'Value2'))
# ]

但是我覺得(對熊貓不太熟悉)有更好的方法可以做到這一點,所以請隨時糾正我。

編輯:在寫這個答案時,@sammywemmy 發布了一個替代方案,在我看來這更符合習慣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM