#python #matrix
#python #матрица
Вопрос:
Я написал код на Python для создания матрицы вероятности перехода из данных, но я продолжаю получать неправильные значения для двух конкретных точек данных. Я потратил несколько дней на попытки разобраться в проблеме, но безуспешно.
О коде: Входные данные представляют собой 4 столбца в файле csv. После подготовки данных первые два столбца представляют собой новые и старые значения состояния. Мне нужно вычислить, как часто каждое старое значение состояния переходит в новое (в основном, как часто каждая пара (x, y) встречается в первых двух столбцах данных). Значения в этих столбцах от 0 до 99. В матрице trans_pr я хочу получить число, как часто пара (x, y) встречается в данных, и иметь это число в соответствующих координатах (x, y) в матрице trans_pr. Поскольку значения от 0 до 99, я могу просто добавлять 1 к матрице в этих координатах каждый раз, когда они встречаются в данных.
Проблема: код работает нормально, но я всегда получаю нули в координатах (:, 29) и (:, 58) и (29,:) и (58;:), несмотря на наличие наблюдений там. Также иногда кажется, что число в этих координатах добавляется к предыдущей строке. Опять же, для меня это не имеет никакого смысла.
Я был бы очень признателен, если бы кто-нибудь мог помочь. (Я новичок в Python, поэтому код, вероятно, неэффективен, но важна только ошибка.)
Код настолько прост, насколько это возможно:
from numpy import *
import csv
my_data = genfromtxt('99c_test.csv', delimiter=',')
"""prepares data for further calculations"""
my_data1=zeros((len(my_data),4))
my_data1[1:,0]=100*my_data[1:,0]
my_data1[1:,1]=100*my_data[1:,3]
my_data1[1:,2]=my_data[1:,1]
my_data1[1:,3]=my_data[1:,2]
my_data2=my_data1
trans_pr=zeros((101,101))
print my_data2
"""fills the matrix with frequencies of observations"""
for i in range(len(my_data2)):
trans_pr[my_data2[i,1],my_data2[i,0]]=trans_pr[my_data2[i,1],my_data2[i,0]] 1
c = csv.writer(open("trpr1.csv", "wb"))
c.writerows(trans_pr)
Вы можете протестировать код с помощью этого ввода (просто сохраните его как CSV-файл):
p_cent,p_euro,p_euro_old,p_cent_old
0.01,1,1,0.28
0.01,1,1,0.29
0.01,1,1,0.3
0.01,1,1,0.28
0.01,1,1,0.29
0.01,1,1,0.3
0.01,1,1,0.57
0.01,1,1,0.58
0.01,1,1,0.59
0.01,1,1,0.6
Комментарии:
1. Это валюта? Я бы посоветовал вам взглянуть на
decimal
библиотеку Python.
Ответ №1:
Это звучит очень похоже на проблему с округлением. Я бы предположил, что, например, 100 * 0,29 (как число с плавающей запятой) округляется в меньшую сторону (т. Е. усекается) и, таким образом, дает 28 вместо 29. Попробуйте округлить числа самостоятельно (т. Е. округление вверх / вниз), прежде чем использовать их в качестве индекса массива.
Обновление: Проверил мою гипотезу, протестировав ее, даже цифры такие, как описано выше — смотрите здесь.
Комментарии:
1. Это сработало. Я подозревал, что это может быть связано с тем, что python странным образом обрабатывает числа, но не знал, что делать. Большое вам спасибо!
Ответ №2:
Вы можете найти rint()
полезную информацию из numpy
. Значение округляется до ближайшего целого числа (см. numpy.rint()
документ). Вы пробовали следующее :
for i in range(len(my_data2)):
trans_pr[rint(my_data2[i,1]), rint(my_data2[i,0])] =
trans_pr[rint(my_data2[i,1]), rint(my_data2[i,0])] 1
Комментарии:
1. Извините, не было ясно.
rint
это не известная мне функция Python; ее нет во встроенном пространстве имен или вmath
.2. Вы правы, это не во встроенном пространстве имен и не в
math
, а изnumpy
. Поскольку она импортирована в начале, я предположил, что ее можно использовать. Теперь добавляю эту деталь в мой ответ, спасибо.