作为单元测试的一部分,我需要测试两个DataFrames是否相等.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
Run Code Online (Sandbox Code Playgroud)
结果是:
Exception: Can only compare identically-labeled DataFrame objects
Run Code Online (Sandbox Code Playgroud)
我相信表达式df1 == df2应该评估为包含所有True值的DataFrame .显然,==在这种情况下,正确的功能应该是有争议的.我的问题是:是否有一个Pandas方法可以满足我的需求?也就是说,有没有办法进行忽略列顺序的相等比较?
Qua*_*ant 31
最常见的意图是这样处理的:
def assertFrameEqual(df1, df2, **kwds ):
""" Assert that two dataframes are equal, ignoring ordering of columns"""
from pandas.util.testing import assert_frame_equal
return assert_frame_equal(df1.sort_index(axis=1), df2.sort_index(axis=1), check_names=True, **kwds )
Run Code Online (Sandbox Code Playgroud)
当然,请参阅pandas.util.testing.assert_frame_equal您可以传递的其他参数
And*_*den 14
您可以使用sort_index以下方式对列进
df1.sort_index(axis=1) == df2.sort_index(axis=1)
Run Code Online (Sandbox Code Playgroud)
这将评估所有True值的数据帧.
由于@osa评论这对于NaN来说是失败的并且也不是特别强大,实际上可能建议使用类似于@ quant的答案(注意:如果有问题,我们想要一个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
Run Code Online (Sandbox Code Playgroud)
通常,您需要快速测试,而对于较大的索引,排序方法可能效率极低(例如,如果您使用行而不是列来解决此问题)。排序方法还容易受到非唯一索引的漏报的影响。
\n\n幸运的是,pandas.util.testing.assert_frame_equal此后已更新了一个check_like选项。将其设置为 true,测试中将不考虑排序。
使用非唯一索引,您将获得神秘的ValueError: cannot reindex from a duplicate axis. reindex_like这是由重新排列其中一个 DataFrame 以匹配另一个 DataFrame 的顺序的底层操作引起的。重新索引很多,如下所示。
import pandas as pd\nfrom pandas.util.testing import assert_frame_equal\n\ndf = pd.DataFrame(np.arange(1e6))\ndf1 = df.sample(frac=1, random_state=42)\ndf2 = df.sample(frac=1, random_state=43)\n\n%timeit -n 1 -r 5 assert_frame_equal(df1.sort_index(), df2.sort_index())\n## 5.73 s \xc2\xb1 329 ms per loop (mean \xc2\xb1 std. dev. of 5 runs, 1 loop each)\n\n%timeit -n 1 -r 5 assert_frame_equal(df1, df2, check_like=True)\n## 1.04 s \xc2\xb1 237 ms per loop (mean \xc2\xb1 std. dev. of 5 runs, 1 loop each)\nRun Code Online (Sandbox Code Playgroud)\n\n对于那些喜欢良好性能比较图的人:
\n\n重新索引与 int 和 str 索引排序(str 更剧烈)
\ndef 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()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
23916 次 |
| 最近记录: |