1. ホーム
  2. パイソン

[解決済み】2つのDataFrameを比較し、その差分を並べて出力する。

2022-04-10 09:13:23

質問

2つのデータフレームの間で何が変更されたかを正確に強調表示しようとしています。

Python Pandasのデータフレームが2つあるとします。

"StudentRoster Jan-1":
id   Name   score                    isEnrolled           Comment
111  Jack   2.17                     True                 He was late to class
112  Nick   1.11                     False                Graduated
113  Zoe    4.12                     True       

"StudentRoster Jan-2":
id   Name   score                    isEnrolled           Comment
111  Jack   2.17                     True                 He was late to class
112  Nick   1.21                     False                Graduated
113  Zoe    4.12                     False                On vacation

私の目標は、次のようなHTMLテーブルを出力することです。

  1. 変更のあった行を特定する(int、float、boolean、stringのいずれでも可)
  2. 同じ値、OLD値、NEW値を持つ行を出力し(理想的にはHTMLテーブルに)、消費者が2つのデータフレーム間で何が変わったかを明確に分かるようにします。

    "StudentRoster Difference Jan-1 - Jan-2":  
    id   Name   score                    isEnrolled           Comment
    112  Nick   was 1.11| now 1.21       False                Graduated
    113  Zoe    4.12                     was True | now False was "" | now   "On   vacation"
    
    

行単位、列単位で比較すればいいのでしょうが、もっと簡単な方法はないのでしょうか?

どのように解決するのですか?

最初の部分は、Constantineと同様に、どの行が空なのかをブール値で取得できます*。

In [21]: ne = (df1 != df2).any(1)

In [22]: ne
Out[22]:
0    False
1     True
2     True
dtype: bool

そして、どのエントリーが変更されたかを確認することができます。

In [23]: ne_stacked = (df1 != df2).stack()

In [24]: changed = ne_stacked[ne_stacked]

In [25]: changed.index.names = ['id', 'col']

In [26]: changed
Out[26]:
id  col
1   score         True
2   isEnrolled    True
    Comment       True
dtype: bool

ここでは、最初の項目がインデックスで、2番目の項目が変更されたカラムである。

In [27]: difference_locations = np.where(df1 != df2)

In [28]: changed_from = df1.values[difference_locations]

In [29]: changed_to = df2.values[difference_locations]

In [30]: pd.DataFrame({'from': changed_from, 'to': changed_to}, index=changed.index)
Out[30]:
               from           to
id col
1  score       1.11         1.21
2  isEnrolled  True        False
   Comment     None  On vacation

* 注:重要なのは df1df2 はここで同じインデックスを共有しています。この曖昧さを克服するために、共有されたラベルだけを見るようにするには df1.index & df2.index しかし、それは練習として残しておこうと思う。