Как проверить корреляцию с использованием десятичных чисел/данных с помощью python 3

Спасибо за ваше время.

Я пишу код, проверяющий корреляцию между несколькими наборами данных. Он отлично работает, когда я использую исходные данные (которые я честно не знаю, в каком формате он находится в этой точке), но после того, как я запускаю данные через некоторые уравнения с использованием модуля Decimal, набор данных не будет отображаться при тестировании для корреляции.

Я чувствую себя действительно глупым и новым LOL, я уверен, что это очень легкое решение.

Вот небольшая программа, которую я написал, чтобы продемонстрировать, что я имею в виду.

from decimal import Decimal
import numpy as np
import pandas as pd

a = [Decimal(2.3), Decimal(1.5), Decimal(5.7), Decimal(4.6), Decimal(5.5), Decimal(1.5)]
b = [Decimal(2.1), Decimal(1.2), Decimal(5.3), Decimal(4.4), Decimal(5.3), Decimal(1.7)]

h = [2.3,1.5,5.7,4.6,5.5,1.5]
j = [2.1,1.2,5.3,4.4,5.3,1.7]

corr_data1 = pd.DataFrame({'A': a, 'B': b}) 

corr_data2 = corr_data1.corr()
print(corr_data2)

corr_data3 = pd.DataFrame({'H': h, 'J': j})

corr_data4 = corr_data3.corr()
print(corr_data4)

Данные для обоих списков A и B, а также H и F являются точно такими же, с той лишь разницей, что A и B являются десятичными форматированными числами, где, когда H и F не являются.

Когда программа запускается, A и B возвращаются:

Empty DataFrame
Columns: []
Index: []

и H и J возвращает:

          H         J
H  1.000000  0.995657
J  0.995657  1.000000

Как это сделать, чтобы я мог использовать данные после того, как я провел их через мои уравнения?

Извините за глупый вопрос и благодарю вас за ваше время. Надеюсь, вы все хорошо, счастливые праздники!

Ответ 1

Pandas не распознает данные как числовые значения. Вот как конвертировать ваши данные в float.

corr_data1.astype(float).corr()

#           A         B
# A  1.000000  0.995657
# B  0.995657  1.000000

Это также должно работать, но на самом деле это не так.

pd.to_numeric(corr_data1['A'], errors='coerce')

# 0   NaN
# 1   NaN
# 2   NaN
# 3   NaN
# 4   NaN
# 5   NaN

Ответ 2

Pandas не имеет специальной поддержки для десятичного типа, поэтому он относится к типу "объект". Это означает, что такие методы, как .corr, которые работают только с числовыми столбцами, не будут считать десятичные значащие столбцы числовыми. Многие функции numpy и scipy также не будут корректно работать на Decimals, потому что десятичные объекты нельзя комбинировать с обычными поплавками в математических операциях. (Похоже, что scipy.stats.pearsonr не работает, но scipy.stats.spearmanr делает.)

Для большинства числовых операций в numpy/ pandas вам нужно будет преобразовать ваши данные в float.

Ответ 3

В дополнение к другим тонким ответам, описывающим, как вам понадобятся значения с плавающей запятой, ваша стратегия ввода значений Decimal сильно нарушена.

a = [Decimal(2.3), Decimal(1.5), Decimal(5.7), Decimal(4.6), 
     Decimal(5.5), Decimal(1.5)]

Урожайность:

[Decimal('2.29999999999999982236431605997495353221893310546875'), 
 Decimal('1.5'),  
 Decimal('5.70000000000000017763568394002504646778106689453125'), 
 Decimal('4.5999999999999996447286321199499070644378662109375'), 
 Decimal('5.5'), 
 Decimal('1.5')]

Что печально, так как вы столкнулись со всей этой проблемой, чтобы ввести точные десятичные представления, но Python воспринимал их как литералы float и налагал на них уродливую неточность двоичной с плавающей запятой, прежде чем они могли когда-либо достичь безопасной гавани конструктор Decimal(). Для некоторых счастливых значений, таких как 1.5, проблем нет. float представляет их spot-on. Для других, таких как 2.3, Зло быстро опускается.

Рассмотрим вместо этого:

a = [Decimal('2.3'), Decimal('1.5'), Decimal('5.7'), Decimal('4.6'), 
     Decimal('5.5'), Decimal('1.5')]

Или, поскольку это громоздко:

a = [Decimal(x) for x in '2.3,1.5,5.7,4.6,5.5,1.5'.split(',')]

Либо вы получите четкие, точные десятичные знаки, которые вы ищете:

[Decimal('2.3'),
 Decimal('1.5'),
 Decimal('5.7'),
 Decimal('4.6'),
 Decimal('5.5'),
 Decimal('1.5')]