Ошибка Python при создании матриц

#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 . Поскольку она импортирована в начале, я предположил, что ее можно использовать. Теперь добавляю эту деталь в мой ответ, спасибо.