@@ -55,11 +55,39 @@ cpdef assert_dict_equal(a, b, bint compare_keys=True):
55
55
56
56
return True
57
57
58
- cpdef assert_almost_equal(a, b, bint check_less_precise = False ):
58
+ cpdef assert_almost_equal(a, b, bint check_less_precise = False ,
59
+ obj = None , lobj = None , robj = None ):
60
+ """ Check that left and right objects are almost equal.
61
+
62
+ Parameters
63
+ ----------
64
+ a : object
65
+ b : object
66
+ check_less_precise : bool, default False
67
+ Specify comparison precision.
68
+ 5 digits (False) or 3 digits (True) after decimal points are compared.
69
+ obj : str, default None
70
+ Specify object name being compared, internally used to show appropriate
71
+ assertion message
72
+ lobj : str, default None
73
+ Specify left object name being compared, internally used to show
74
+ appropriate assertion message
75
+ robj : str, default None
76
+ Specify right object name being compared, internally used to show
77
+ appropriate assertion message
78
+ """
79
+
59
80
cdef:
60
81
int decimal
82
+ double diff = 0.0
61
83
Py_ssize_t i, na, nb
62
84
double fa, fb
85
+ bint is_unequal = False
86
+
87
+ if lobj is None :
88
+ lobj = a
89
+ if robj is None :
90
+ robj = b
63
91
64
92
if isinstance (a, dict ) or isinstance (b, dict ):
65
93
return assert_dict_equal(a, b)
@@ -70,33 +98,62 @@ cpdef assert_almost_equal(a, b, bint check_less_precise=False):
70
98
return True
71
99
72
100
if isiterable(a):
73
- assert isiterable(b), (
74
- " First object is iterable, second isn't: %r != %r " % (a, b)
75
- )
101
+
102
+ if not isiterable(b):
103
+ from pandas.util.testing import raise_assert_detail
104
+ if obj is None :
105
+ obj = ' Iterable'
106
+ msg = " First object is iterable, second isn't"
107
+ raise_assert_detail(obj, msg, a, b)
108
+
76
109
assert has_length(a) and has_length(b), (
77
110
" Can't compare objects without length, one or both is invalid: "
78
111
" (%r , %r )" % (a, b)
79
112
)
80
113
81
- na, nb = len (a), len (b)
82
- assert na == nb, (
83
- " Length of two iterators not the same: %r != %r " % (na, nb)
84
- )
85
114
if isinstance (a, np.ndarray) and isinstance (b, np.ndarray):
115
+ if obj is None :
116
+ obj = ' numpy array'
117
+ na, nb = a.size, b.size
118
+ if a.shape != b.shape:
119
+ from pandas.util.testing import raise_assert_detail
120
+ raise_assert_detail(obj, ' {0} shapes are different' .format(obj),
121
+ a.shape, b.shape)
86
122
try :
87
123
if np.array_equal(a, b):
88
124
return True
89
125
except :
90
126
pass
127
+ else :
128
+ if obj is None :
129
+ obj = ' Iterable'
130
+ na, nb = len (a), len (b)
131
+
132
+ if na != nb:
133
+ from pandas.util.testing import raise_assert_detail
134
+ raise_assert_detail(obj, ' {0} length are different' .format(obj),
135
+ na, nb)
136
+
137
+ for i in xrange (len (a)):
138
+ try :
139
+ assert_almost_equal(a[i], b[i], check_less_precise)
140
+ except AssertionError :
141
+ is_unequal = True
142
+ diff += 1
91
143
92
- for i in xrange (na):
93
- assert_almost_equal(a[i], b[i], check_less_precise)
144
+ if is_unequal:
145
+ from pandas.util.testing import raise_assert_detail
146
+ msg = ' {0} values are different ({1} %)' .format(obj, np.round(diff * 100.0 / na, 5 ))
147
+ raise_assert_detail(obj, msg, lobj, robj)
94
148
95
149
return True
150
+
96
151
elif isiterable(b):
97
- assert False , (
98
- " Second object is iterable, first isn't: %r != %r " % (a, b)
99
- )
152
+ from pandas.util.testing import raise_assert_detail
153
+ if obj is None :
154
+ obj = ' Iterable'
155
+ msg = " Second object is iterable, first isn't"
156
+ raise_assert_detail(obj, msg, a, b)
100
157
101
158
if isnull(a):
102
159
assert isnull(b), (
0 commit comments