Entiende el código de forma correcta antes de usarlo a tu trabajo si tquieres aportar algo puedes compartirlo con nosotros.
Solución:
Si no te importa usar pandas
hay una línea para extraer las probabilidades de transición:
pd.crosstab(pd.Series(days[1:],name='Tomorrow'),
pd.Series(days[:-1],name='Today'),normalize=1)
Producción:
Today clouds rain sun
Tomorrow
clouds 0.40625 0.230769 0.309524
rain 0.28125 0.423077 0.142857
sun 0.31250 0.346154 0.547619
Aquí la probabilidad (adelante) de que mañana estará soleado dado que hoy llovió se encuentra en la columna ‘lluvia’, fila ‘sol’. Si desea tener probabilidades hacia atrás (cuál podría haber sido el clima ayer dado el clima de hoy), cambie los dos primeros parámetros.
Si desea tener las probabilidades almacenadas en filas en lugar de columnas, establezca normalize=0
pero tenga en cuenta que si hiciera eso directamente en este ejemplo, obtendrá probabilidades hacia atrás almacenadas como filas. Si desea obtener el mismo resultado que el anterior pero transpuesto, puede a) sí, transponer o b) cambiar el orden de los dos primeros parámetros y establecer normalize
a 0.
Si solo desea mantener los resultados como numpy
2-d array (y no como un marco de datos de pandas), escriba .values
después del último paréntesis.
Me gusta una combinación de pandas
y itertools
para esto. El bloque de código es un poco más largo que el anterior, pero no confunda verbosidad con velocidad. (Los window
func debe ser muy rápido; la parte de los pandas será más lenta sin duda).
Primero, haga una función de “ventana”. Aquí hay uno del libro de cocina de itertools. Esto te lleva a un lista de tuplas de transiciones (estado1 a estado2).
from itertools import islice
def window(seq, n=2):
"Sliding window width n from seq. From old itertools recipes."""
it = iter(seq)
result = tuple(islice(it, n))
if len(result) == n:
yield result
for elem in it:
result = result[1:] + (elem,)
yield result
# list(window(days))
# [('rain', 'rain'),
# ('rain', 'rain'),
# ('rain', 'clouds'),
# ('clouds', 'rain'),
# ('rain', 'sun'),
# ...
Luego use una operación pandas groupby + value counts para obtener una matriz de transición de cada estado1 a cada estado2:
import pandas as pd
pairs = pd.DataFrame(window(days), columns=['state1', 'state2'])
counts = pairs.groupby('state1')['state2'].value_counts()
probs = (counts / counts.sum()).unstack()
Tu resultado se ve así:
print(probs)
state2 clouds rain sun
state1
clouds 0.13 0.09 0.10
rain 0.06 0.11 0.09
sun 0.13 0.06 0.23
Aquí hay una solución numérica “pura” que crea tablas de 3×3 donde el cero dim (número de fila) corresponde a hoy y el último dim (número de columna) corresponde a mañana.
La conversión de palabras a índices se realiza truncando después de la primera letra y luego usando una tabla de búsqueda.
para contar numpy.add.at
se usa
Esto fue escrito con la eficiencia en mente. Hace un millón de palabras en menos de un segundo.
import numpy as np
report = [
'rain', 'rain', 'rain', 'clouds', 'rain', 'sun', 'clouds', 'clouds',
'rain', 'sun', 'rain', 'rain', 'clouds', 'clouds', 'sun', 'sun',
'clouds', 'clouds', 'rain', 'clouds', 'sun', 'rain', 'rain', 'sun',
'sun', 'clouds', 'clouds', 'rain', 'rain', 'sun', 'sun', 'rain',
'rain', 'sun', 'clouds', 'clouds', 'sun', 'sun', 'clouds', 'rain',
'rain', 'rain', 'rain', 'sun', 'sun', 'sun', 'sun', 'clouds', 'sun',
'clouds', 'clouds', 'sun', 'clouds', 'rain', 'sun', 'sun', 'sun',
'clouds', 'sun', 'rain', 'sun', 'sun', 'sun', 'sun', 'clouds',
'rain', 'clouds', 'clouds', 'sun', 'sun', 'sun', 'sun', 'sun', 'sun',
'clouds', 'clouds', 'clouds', 'clouds', 'clouds', 'sun', 'rain',
'rain', 'rain', 'clouds', 'sun', 'clouds', 'clouds', 'clouds', 'rain',
'clouds', 'rain', 'sun', 'sun', 'clouds', 'sun', 'sun', 'sun', 'sun',
'sun', 'sun', 'rain']
# create np array, keep only first letter (by forcing dtype)
# obviously, this only works because rain, sun, clouds start with different
# letters
# cast to int type so we can use for indexing
ri = np.array(report, dtype='|S1').view(np.uint8)
# create lookup
c, r, s = 99, 114, 115 # you can verify this using chr and ord
lookup = np.empty((s+1,), dtype=int)
lookup[[c, r, s]] = np.arange(3)
# translate c, r, s to 0, 1, 2
rc = lookup[ri]
# get counts (of pairs (today, tomorrow))
cnts = np.zeros((3, 3), dtype=int)
np.add.at(cnts, (rc[:-1], rc[1:]), 1)
# or as probs
probs = cnts / cnts.sum()
# or as condional probs (if today is sun how probable is rain tomorrow etc.)
cond = cnts / cnts.sum(axis=-1, keepdims=True)
print(cnts)
print(probs)
print(cond)
# [13 9 10]
# [ 6 11 9]
# [13 6 23]]
# [[ 0.13 0.09 0.1 ]
# [ 0.06 0.11 0.09]
# [ 0.13 0.06 0.23]]
# [[ 0.40625 0.28125 0.3125 ]
# [ 0.23076923 0.42307692 0.34615385]
# [ 0.30952381 0.14285714 0.54761905]]
Agradecemos que desees añadir valor a nuestro contenido informacional colaborando tu veteranía en las ilustraciones.