NumPy: конвертировать десятичные дроби в дроби

Я вычисляю обратную матрицу A, например,

import numpy as np

A = np.diag([1, 2, 3])
A_inv = np.linalg.pinv(A)
print(A_inv)

Я получил,

[[ 1.          0.          0.        ]
 [ 0.          0.5         0.        ]
 [ 0.          0.          0.33333333]]

Но я хочу этого,

[[ 1.          0.          0. ]
 [ 0.          1/2         0. ]
 [ 0.          0.          1/3]]

Я пробовал np.set_printoptions,

import fractions
np.set_printoptions(formatter={'all':lambda x: str(fractions.Fraction(x))})
print(A_inv)

но я получил это,

[[1 0 0]
 [0 1/2 0]
 [0 0 6004799503160661/18014398509481984]]

Как преобразовать десятичные дроби в дроби в NumPy?


person SparkAndShine    schedule 13.02.2017    source источник
comment
Вы просто говорите о представлении при печати? Или вы действительно хотите, чтобы numpy инвертировал матрицу, используя что-то вроде fractions.Fraction?   -  person mgilson    schedule 13.02.2017
comment
@mgilson, только для печати.   -  person SparkAndShine    schedule 13.02.2017
comment
вы сталкиваетесь с проблемами с плавающей запятой, попробуйте что-то вроде lambda x: str(fractions.Fraction(x).limit_denominator())   -  person jeremycg    schedule 13.02.2017
comment
@jeremycg, это работает :-)   -  person SparkAndShine    schedule 13.02.2017


Ответы (1)


Это проблема с плавающей запятой - помните, что 2/3 не совсем 2/3 в представлении Python.

Класс Fraction имеет встроенный метод limit_denominator(), чтобы позаботиться об этом:

import fractions
np.set_printoptions(formatter={'all':lambda x: str(fractions.Fraction(x).limit_denominator())})
print(A_inv)

Что дает желаемый ответ:

[[1 0 0]
 [0 1/2 0]
 [0 0 1/3]]
person jeremycg    schedule 13.02.2017
comment
Имейте в виду, что limit_denominator делает что-то очень конкретное, а именно находит ближайшее рациональное приближение со знаменателем, не превышающим 1 миллион. Это может быть или не быть подходящим, в зависимости от варианта использования. В частности, это не даст особенно хороших результатов для очень больших или очень малых чисел. - person Mark Dickinson; 13.02.2017
comment
Большое спасибо. У вас есть идея форматировать печать каждого элемента в фиксированную ширину? Я использовал np.set_printoptions(formatter={'str_kind': '{10s}'.format}, но это не сработало. - person SparkAndShine; 13.02.2017