Python将dict与csr_矩阵作为值进行比较

Python将dict与csr_矩阵作为值进行比较,python,numpy,dictionary,sparse-matrix,unit-testing,Python,Numpy,Dictionary,Sparse Matrix,Unit Testing,我有两个变量r和e,它们都是字典,字符串作为键,csr\u矩阵作为值。现在我想断言他们是平等的。我该怎么做 尝试1: from scipy.sparse.csr import csr_matrix import numpy as np def test_dict_equals(self): r = {'a': csr_matrix([[0, 0 ,1], [0, 1, 0], [1, 0, 0]])} e = {'a': csr_matrix([[0, 0 ,1], [0, 1

我有两个变量
r
e
,它们都是字典,字符串作为键,csr\u矩阵作为值。现在我想断言他们是平等的。我该怎么做

尝试1:

from scipy.sparse.csr import csr_matrix
import numpy as np

def test_dict_equals(self):
    r = {'a': csr_matrix([[0, 0 ,1], [0, 1, 0], [1, 0, 0]])}
    e = {'a': csr_matrix([[0, 0 ,1], [0, 1, 0], [1, 0, 0]])}
    self.assertDictEqual(r, e)
def test_dict_equals(self):
    r = {'a': csr_matrix([[0, 0 ,1.01], [0, 1, 0], [1, 0, 0]])}
    e = {'a': csr_matrix([[0, 0 ,1.01], [0, 1, 0], [1, 0, 0]])}
    self.assertListEqual(r.keys(), e.keys())
    for k in r.keys():
        np.testing.assert_allclose(r[k], e[k])
def test_dict_equals(self):
    r = {'a': csr_matrix([[0, 0 ,1.01], [0, 1, 0], [1, 0, 0]])}
    e = {'a': csr_matrix([[0, 0 ,1.01], [0, 1, 0], [1, 0, 0]])}
    self.assertListEqual(list(r.keys()), list(e.keys()))
    for k in r.keys():
        np.testing.assert_allclose(r[k], e[k])
这不起作用:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all().
AssertionError: First sequence is not a list: dict_keys(['a'])
TypeError: ufunc 'isinf' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
尝试2:

from scipy.sparse.csr import csr_matrix
import numpy as np

def test_dict_equals(self):
    r = {'a': csr_matrix([[0, 0 ,1], [0, 1, 0], [1, 0, 0]])}
    e = {'a': csr_matrix([[0, 0 ,1], [0, 1, 0], [1, 0, 0]])}
    self.assertDictEqual(r, e)
def test_dict_equals(self):
    r = {'a': csr_matrix([[0, 0 ,1.01], [0, 1, 0], [1, 0, 0]])}
    e = {'a': csr_matrix([[0, 0 ,1.01], [0, 1, 0], [1, 0, 0]])}
    self.assertListEqual(r.keys(), e.keys())
    for k in r.keys():
        np.testing.assert_allclose(r[k], e[k])
def test_dict_equals(self):
    r = {'a': csr_matrix([[0, 0 ,1.01], [0, 1, 0], [1, 0, 0]])}
    e = {'a': csr_matrix([[0, 0 ,1.01], [0, 1, 0], [1, 0, 0]])}
    self.assertListEqual(list(r.keys()), list(e.keys()))
    for k in r.keys():
        np.testing.assert_allclose(r[k], e[k])
这也不起作用:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all().
AssertionError: First sequence is not a list: dict_keys(['a'])
TypeError: ufunc 'isinf' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
尝试3:

from scipy.sparse.csr import csr_matrix
import numpy as np

def test_dict_equals(self):
    r = {'a': csr_matrix([[0, 0 ,1], [0, 1, 0], [1, 0, 0]])}
    e = {'a': csr_matrix([[0, 0 ,1], [0, 1, 0], [1, 0, 0]])}
    self.assertDictEqual(r, e)
def test_dict_equals(self):
    r = {'a': csr_matrix([[0, 0 ,1.01], [0, 1, 0], [1, 0, 0]])}
    e = {'a': csr_matrix([[0, 0 ,1.01], [0, 1, 0], [1, 0, 0]])}
    self.assertListEqual(r.keys(), e.keys())
    for k in r.keys():
        np.testing.assert_allclose(r[k], e[k])
def test_dict_equals(self):
    r = {'a': csr_matrix([[0, 0 ,1.01], [0, 1, 0], [1, 0, 0]])}
    e = {'a': csr_matrix([[0, 0 ,1.01], [0, 1, 0], [1, 0, 0]])}
    self.assertListEqual(list(r.keys()), list(e.keys()))
    for k in r.keys():
        np.testing.assert_allclose(r[k], e[k])
这也不起作用:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all().
AssertionError: First sequence is not a list: dict_keys(['a'])
TypeError: ufunc 'isinf' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

assertDictEqual
函数将调用对象的
方法。在
csr\u矩阵
的源代码中,您可以看到没有
方法

您必须编写一个子类
csr\u matrix
,然后执行断言。下面是一个
numpy.ndarray
的示例。代码必须相似

import copy
import numpy
import unittest

class SaneEqualityArray(numpy.ndarray):
    def __eq__(self, other):
        return (isinstance(other, SaneEqualityArray) and
                self.shape == other.shape and
                numpy.ndarray.__eq__(self, other).all())

class TestAsserts(unittest.TestCase):

    def testAssert(self):
        tests = [
            [1, 2],
            {'foo': 2},
            [2, 'foo', {'d': 4}],
            SaneEqualityArray([1, 2]),
            {'foo': {'hey': SaneEqualityArray([2, 3])}},
            [{'foo': SaneEqualityArray([3, 4]), 'd': {'doo': 3}},
             SaneEqualityArray([5, 6]), 34]
        ]
        for t in tests:
            self.assertEqual(t, copy.deepcopy(t))

if __name__ == '__main__':
    unittest.main()

希望有帮助。

assertDictEqual
函数将调用对象的
方法。在
csr\u矩阵
的源代码中,您可以看到没有
方法

您必须编写一个子类
csr\u matrix
,然后执行断言。下面是一个
numpy.ndarray
的示例。代码必须相似

import copy
import numpy
import unittest

class SaneEqualityArray(numpy.ndarray):
    def __eq__(self, other):
        return (isinstance(other, SaneEqualityArray) and
                self.shape == other.shape and
                numpy.ndarray.__eq__(self, other).all())

class TestAsserts(unittest.TestCase):

    def testAssert(self):
        tests = [
            [1, 2],
            {'foo': 2},
            [2, 'foo', {'d': 4}],
            SaneEqualityArray([1, 2]),
            {'foo': {'hey': SaneEqualityArray([2, 3])}},
            [{'foo': SaneEqualityArray([3, 4]), 'd': {'doo': 3}},
             SaneEqualityArray([5, 6]), 34]
        ]
        for t in tests:
            self.assertEqual(t, copy.deepcopy(t))

if __name__ == '__main__':
    unittest.main()

希望有帮助。:

暂时忘掉字典,集中精力比较2个
稀疏矩阵。它们不是
numpy
数组,因此不能直接使用
np
方法。这就是你第三次尝试失败的原因

有一个
scipy.sparse
unittesting目录。我还没有研究过它,但它可能会给你一些超出我下面建议的想法

它们是不同的对象

id(A)==id(B) # False
它们具有相同数量的非零

A.nnz == B.nnz  # True - just a comparison of 2 numbers
此稀疏格式的数据包含在3个数组中,
A.data
A.index
A.indptr
。因此,您可以使用
np
方法来测试其中的一个或多个

np.allclose(A.data, B.data)   # this would also compare dtype
你也可以比较形状等等

较新版本的
scipy
实现了稀疏矩阵的逐元素比较器<代码>=
已实现,但可能会给您一个警告:

SparseEfficiencyWarning:使用==比较稀疏矩阵效率低下,请尝试使用!=相反

如果形状匹配,这可能是比较稀疏矩阵的有效方法:

(A!=B).nnz==0 
如果形状不匹配,
A=C
返回
True

如果它们很小,你可以比较它们的稠密等价物:

np.allclose(A.A, B.A)

暂时忘掉字典,专注于比较2个稀疏矩阵。它们不是
numpy
数组,因此不能直接使用
np
方法。这就是你第三次尝试失败的原因

有一个
scipy.sparse
unittesting目录。我还没有研究过它,但它可能会给你一些超出我下面建议的想法

它们是不同的对象

id(A)==id(B) # False
它们具有相同数量的非零

A.nnz == B.nnz  # True - just a comparison of 2 numbers
此稀疏格式的数据包含在3个数组中,
A.data
A.index
A.indptr
。因此,您可以使用
np
方法来测试其中的一个或多个

np.allclose(A.data, B.data)   # this would also compare dtype
你也可以比较形状等等

较新版本的
scipy
实现了稀疏矩阵的逐元素比较器<代码>=
已实现,但可能会给您一个警告:

SparseEfficiencyWarning:使用==比较稀疏矩阵效率低下,请尝试使用!=相反

如果形状匹配,这可能是比较稀疏矩阵的有效方法:

(A!=B).nnz==0 
如果形状不匹配,
A=C
返回
True

如果它们很小,你可以比较它们的稠密等价物:

np.allclose(A.A, B.A)

谢谢我现在确实在测试A.data、A.index和A.indptr。您所指的测试目录是用于实现csr_矩阵的测试代码,而不是用于测试的辅助函数。注意:可能有两个相同的矩阵,但具有不同的indptr/索引/数据数组。因此,对于这两个元素,非零元素的顺序不相同。这会导致错误检测到不相等。谢谢。我现在确实在测试A.data、A.index和A.indptr。您所指的测试目录是用于实现csr_矩阵的测试代码,而不是用于测试的辅助函数。注意:可能有两个相同的矩阵,但具有不同的indptr/索引/数据数组。因此,对于这两个元素,非零元素的顺序不相同。这会导致错误检测到不相等。