Как создать таблицу переходов из нескольких последовательностей?

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