2015-01-06 2 views
0

У меня есть две переменные r и e, которые оба являются словарями, со строками как ключи и csr_matrices как значения. Теперь я хочу утверждать, что они равны. Как мне это сделать?Python сравнить dict с csr_matrices как значения

Попробуйте 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) 

Это не работает:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all(). 

Попробуйте 2:

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]) 

Это также не работает:

AssertionError: First sequence is not a list: dict_keys(['a']) 

Попробуйте 3:

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]) 

Это также не работает:

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'' 

ответ

1

assertDictEqual функция будет вызывать __eq__ метод объектов. В исходном коде csr_matrix вы можете увидеть, что нет метода __eq__.

Вы должны написать подкласс csr_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() 

Надеется, что это помогает. :)

1

Забудьте о словаре на данный момент, и сосредоточиться на сравнение 2 sparse матрицы. Они не являются numpy массивами, поэтому вы не можете напрямую использовать методы np. Вот почему ваша третья попытка не работает.

Существует scipy.sparse unittesting directory. Я не изучил его, но он может дать вам идеи, кроме тех, которые я предлагаю ниже.

https://github.com/scipy/scipy/tree/master/scipy/sparse/tests

A=sparse.csr_matrix(np.arange(9).reshape(3,3)) 
B=sparse.csr_matrix(np.arange(9).reshape(3,3)) 

Они являются разные объекты

id(A)==id(B) # False 

Они имеют одинаковое количество ненулевых

A.nnz == B.nnz # True - just a comparison of 2 numbers 

Данные для этого разреженного формата содержится в 3-х массивов, A.data , A.indices, 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) 
+0

Спасибо. Я действительно тестирую A.data, A.indices и A.indptr. Каталог тестирования, на который вы ссылаетесь, является тестовым кодом для реализации csr_matrix, а не вспомогательных функций для тестирования. – physicalattraction

+0

Примечание: возможно иметь две идентичные матрицы, но с различными индексами/индексами/массивами данных. Элементы, отличные от нуля, тогда не совпадают для обоих. Это приводит к ложному обнаружению неравновесия. – physicalattraction

Смежные вопросы