29

単体テストの一環として、2つのDataFrameが等しいかどうかをテストする必要があります。DataFrameの列の順序は私にとって重要ではありません。ただし、パンダにとっては重要なようです。

import pandas
df1 = pandas.DataFrame(index = [1,2,3,4])
df2 = pandas.DataFrame(index = [1,2,3,4])
df1['A'] = [1,2,3,4]
df1['B'] = [2,3,4,5]
df2['B'] = [2,3,4,5]
df2['A'] = [1,2,3,4]
df1 == df2

結果:

Exception: Can only compare identically-labeled DataFrame objects

df1 == df2は、すべての値を含むDataFrameに評価される必要があると思いTrueます。明らかに==、このコンテキストでの正しい機能がどうあるべきかについては議論の余地があります。私の質問は:私が望むことをするパンダの方法はありますか?つまり、列の順序を無視する等式比較を行う方法はありますか?

4

9 に答える 9

20

次を使用して列をソートできますsort_index

df1.sort_index(axis=1) == df2.sort_index(axis=1)

これは、すべてのTrue値のデータフレームに評価されます。


@osa がコメントしているように、これは NaN では失敗し、特に堅牢でもありません。実際には、@quant の回答に似たものを使用することをお勧めします (注: 問題がある場合は、raise ではなく bool が必要です)。

def my_equal(df1, df2):
    from pandas.util.testing import assert_frame_equal
    try:
        assert_frame_equal(df1.sort_index(axis=1), df2.sort_index(axis=1), check_names=True)
        return True
    except (AssertionError, ValueError, TypeError):  perhaps something else?
        return False
于 2013-01-08T21:38:58.643 に答える
5
def equal( df1, df2 ):
    """ Check if two DataFrames are equal, ignoring nans """
    return df1.fillna(1).sort_index(axis=1).eq(df2.fillna(1).sort_index(axis=1)).all().all()
于 2013-10-10T19:30:53.717 に答える
2

列の並べ替えは、行と列のラベルがフレーム全体で一致する場合にのみ機能します。たとえば、セルの値が同じでラベルが異なる2つのデータフレームがあると、ソートソリューションは機能しません。pandas を使用して k モード クラスタリングを実装するときに、このシナリオに遭遇しました。

セルの等価性をチェックする単純なequals関数で回避しました(以下のコード)

def frames_equal(df1,df2) :
    if not isinstance(df1,DataFrame) or not isinstance(df2,DataFrame) :
        raise Exception(
            "dataframes should be an instance of pandas.DataFrame")

    if df1.shape != df2.shape:
        return False

    num_rows,num_cols = df1.shape
    for i in range(num_rows):
       match = sum(df1.iloc[i] == df2.iloc[i])
       if match != num_cols :
          return False
   return True
于 2015-07-17T04:47:41.887 に答える
1

おそらく、行と列の両方の順序を無視して DataFrame を比較する関数が必要になるでしょうか? 唯一の要件は、インデックスとして使用するための一意の列を持つことです。

f1 = pd.DataFrame([
    {"id": 1, "foo": "1", "bar": None},
    {"id": 2, "foo": "2", "bar": 2},
    {"id": 3, "foo": "3", "bar": 3},
    {"id": 4, "foo": "4", "bar": 4}
])
f2 = pd.DataFrame([
    {"id": 3, "foo": "3", "bar": 3},
    {"id": 1, "bar": None, "foo": "1",},
    {"id": 2, "foo": "2", "bar": 2},
    {"id": 4, "foo": "4", "bar": 4}
])

def comparable(df, index_col='id'):
    return df.fillna(value=0).set_index(index_col).to_dict('index')

comparable(f1) == comparable (f2)  # returns True
于 2019-07-11T08:06:07.123 に答える