Ste*_*ike 26 python equality nan pandas
在单元测试一些函数的上下文中,我试图使用python pandas建立2个DataFrame的相等性:
ipdb> expect
1 2
2012-01-01 00:00:00+00:00 NaN 3
2013-05-14 12:00:00+00:00 3 NaN
ipdb> df
identifier 1 2
timestamp
2012-01-01 00:00:00+00:00 NaN 3
2013-05-14 12:00:00+00:00 3 NaN
ipdb> df[1][0]
nan
ipdb> df[1][0], expect[1][0]
(nan, nan)
ipdb> df[1][0] == expect[1][0]
False
ipdb> df[1][1] == expect[1][1]
True
ipdb> type(df[1][0])
<type 'numpy.float64'>
ipdb> type(expect[1][0])
<type 'numpy.float64'>
ipdb> (list(df[1]), list(expect[1]))
([nan, 3.0], [nan, 3.0])
ipdb> df1, df2 = (list(df[1]), list(expect[1])) ;; df1 == df2
False
Run Code Online (Sandbox Code Playgroud)
鉴于我试图expect
对整个(df
包括NaN
职位)进行全面测试,我做错了什么?
比较包括NaN
s 的Series/DataFrames的相等性的最简单方法是什么?
And*_*den 29
您可以将assert_frame_equals与check_names = False一起使用(以便不检查索引/列名称),如果它们不相等则会引发:
In [11]: from pandas.testing import assert_frame_equal
In [12]: assert_frame_equal(df, expected, check_names=False)
Run Code Online (Sandbox Code Playgroud)
你可以将它包装在一个函数中,例如:
try:
assert_frame_equal(df, expected, check_names=False)
return True
except AssertionError:
return False
Run Code Online (Sandbox Code Playgroud)
在最近的大熊猫中,此功能已添加为.equals
:
df.equals(expected)
Run Code Online (Sandbox Code Playgroud)
Phi*_*oud 17
其中一个特性NaN
是,NaN != NaN
是True
.
看看这个答案是一个很好的方法来使用它numexpr
.
(a == b) | ((a != a) & (b != b))
Run Code Online (Sandbox Code Playgroud)
说这个(伪代码):
a == b or (isnan(a) and isnan(b))
Run Code Online (Sandbox Code Playgroud)
所以,要么a
等于b
或两者a
并b
有NaN
.
如果你有小框架,那就assert_frame_equal
没关系.但是,对于大型框架(10M行)assert_frame_equal
来说几乎没用.我不得不打断它,这花了很长时间.
In [1]: df = DataFrame(rand(1e7, 15))
In [2]: df = df[df > 0.5]
In [3]: df2 = df.copy()
In [4]: df
Out[4]:
<class 'pandas.core.frame.DataFrame'>
Int64Index: 10000000 entries, 0 to 9999999
Columns: 15 entries, 0 to 14
dtypes: float64(15)
In [5]: timeit (df == df2) | ((df != df) & (df2 != df2))
1 loops, best of 3: 598 ms per loop
Run Code Online (Sandbox Code Playgroud)
timeit
(推测)所需单一的,bool
表示两者DataFrame
是否相等:
In [9]: timeit ((df == df2) | ((df != df) & (df2 != df2))).values.all()
1 loops, best of 3: 687 ms per loop
Run Code Online (Sandbox Code Playgroud)
像@PhillipCloud 的回答,但写得更多
In [26]: df1 = DataFrame([[np.nan,1],[2,np.nan]])
In [27]: df2 = df1.copy()
Run Code Online (Sandbox Code Playgroud)
他们真的是等价的
In [28]: result = df1 == df2
In [29]: result[pd.isnull(df1) == pd.isnull(df2)] = True
In [30]: result
Out[30]:
0 1
0 True True
1 True True
Run Code Online (Sandbox Code Playgroud)
df2 中的 nan 在 df1 中不存在
In [31]: df2 = DataFrame([[np.nan,1],[np.nan,np.nan]])
In [32]: result = df1 == df2
In [33]: result[pd.isnull(df1) == pd.isnull(df2)] = True
In [34]: result
Out[34]:
0 1
0 True True
1 False True
Run Code Online (Sandbox Code Playgroud)
您还可以填充一个您知道不在框架中的值
In [38]: df1.fillna(-999) == df1.fillna(-999)
Out[38]:
0 1
0 True True
1 True True
Run Code Online (Sandbox Code Playgroud)
使用 == 与 np.NaN 进行任何相等比较都是 False,甚至 np.NaN == np.NaN 也是 False。
简单地说df1.fillna('NULL') == df2.fillna('NULL')
,如果“NULL”不是原始数据中的值。
为了安全起见,请执行以下操作:
示例 a) 比较两个具有 NaN 值的数据帧
bools = (df1 == df2)
bools[pd.isnull(df1) & pd.isnull(df2)] = True
assert bools.all().all()
Run Code Online (Sandbox Code Playgroud)
示例 b) 过滤 df1 中与 df2 不匹配的行
bools = (df1 != df2)
bools[pd.isnull(df1) & pd.isnull(df2)] = False
df_outlier = df1[bools.all(axis=1)]
Run Code Online (Sandbox Code Playgroud)
(注意:这是错误的 - bools[pd.isnull(df1) == pd.isnull(df2)] = False)
归档时间: |
|
查看次数: |
33550 次 |
最近记录: |