#python #pandas
#python #pandas
Вопрос:
Я хочу создать таблицу переходов из нескольких последовательностей дискретных состояний:
sequence1 = [0, 1, 2, 1, 3, 4, 5, 2, 3, 5, 2, 1, 4]
sequence2 = [1, 0, 1, 1, 2, 1, 3, 4, 4, 4, 3]
...
Я могу создать таблицу переходов из одной последовательности, используя функцию pandas.crosstab:
import pandas as pd
transitions = pd.crosstab(pd.Series(sequence1[1:],name='Next'),
pd.Series(sequence1[:-1],name='Current'),normalize=1)
Как я могу создать таблицу переходов из нескольких последовательностей? (Объединение их в один длинный список приводит к ложным переходам между концом одной последовательности и началом следующей.)
Редактировать: текущий вывод выглядит следующим образом, давая вероятность для каждого перехода в последовательности 1:
>>> transitions
Current 0 1 2 3 4 5
Next
1 1.0 0.000000 0.666667 0.0 0.0 0.0
2 0.0 0.333333 0.000000 0.0 0.0 1.0
3 0.0 0.333333 0.333333 0.0 0.0 0.0
4 0.0 0.333333 0.000000 0.5 0.0 0.0
5 0.0 0.000000 0.000000 0.5 1.0 0.0
Я хочу тот же формат вывода, но вероятности, отражающие несколько входных последовательностей.
Комментарии:
1. можете ли вы вставить ожидаемый результат?
Ответ №1:
Результирующий фрейм данных перехода должен представлять собой квадратный массив, включающий все ваши состояния, но ваш результат таковым не является (в нем нет строки для состояния «0»).
Я также предполагаю, что все ваши последовательности содержат последовательные числа в качестве имен состояний, без «пробелов».
Мое решение еще более общее, оно работает для списка, содержащего произвольное количество исходных последовательностей:
def transitions(allSeq):
# Size of the transition array
n = max([ max(s) for s in allSeq ]) 1
# Transition array, initially empty
arr = np.zeros((n,n), dtype=int)
for s in allSeq:
ind = (s[1:], s[:-1]) # Indices of elements for existing transitions
arr[ind] = 1 # Add existing transitions
# Normalize by columns and return as a DataFrame
return pd.DataFrame(arr / arr.sum(axis=0)).rename_axis(index='Next', columns='Current')
Обратите внимание, что arr / arr.sum(axis=0)
нормализация столбцов выполняется на
Уровень Numpy, а затем результат преобразуется в фрейм данных.
Когда вы вызываете его, передавая список ваших последовательностей:
res = transitions([sequence1, sequence2])
результат:
Current 0 1 2 3 4 5
Next
0 0.0 0.142857 0.000000 0.000000 0.000000 0.0
1 1.0 0.142857 0.666667 0.000000 0.000000 0.0
2 0.0 0.285714 0.000000 0.000000 0.000000 1.0
3 0.0 0.285714 0.333333 0.000000 0.333333 0.0
4 0.0 0.142857 0.000000 0.666667 0.333333 0.0
5 0.0 0.000000 0.000000 0.333333 0.333333 0.0
Конечно, может быть более 2 исходных последовательностей.
Комментарии:
1. Это позволяет мне использовать тип ввода, который я хочу, но я хочу сохранить нормализацию, чтобы получить вероятность каждого перехода, поскольку я использую это для создания цепочки Маркова.