5

Sto cercando un buon modo per archiviare e utilizzare le probabilità condizionali in python.Moltiplicazione del tensore di probabilità utilizzando pandas.DataFrame

Sto pensando di utilizzare un dataframe pandas. Se le probabilità condizionate di alcuni X sono P(X=A|P1=1, P2=1) = 0.2, P(X=B|P1=2, P2=1) = 0.9 ecc, vorrei utilizzare il dataframe

  A B 
P1 P2   
1 1 0.2 0.8 
    2 0.5 0.5 
2 1 0.9 0.1 
    2 0.9 0.1 

e data la probabilità marginali di P1 e P2 come Serie

1 0.4 
2 0.6 
Name: P1 

1 0.7 
2 0.3 
Name: P2 

vorrei ottenere il Serie di probabilità marginali di X, ovvero la serie

A 0.602 
B 0.398 
Name: X 

posso ottenere ciò che voglio da

X = sum(
    sum(
     X.xs(i, level="P1")*P1[i] 
     for i in P1.index 
     ).xs(j)*P2[j] 
    for j in P2.index 
    ) 
X.name="X" 

ma questo non è facilmente generalizzabile a più dipendenze, l'asimmetria tra la prima xs con level e la seconda, senza sembra strano e come al solito quando si lavora con pandas I' Sono molto sicuro che ci sia una soluzione migliore usando i suoi trucchi e metodi.

È pandas un buon strumento per questo, dovrei rappresentare i miei dati in un altro modo, e qual è il modo migliore per fare questo calcolo, che è essenzialmente un prodotto tensoriale indicizzato, in pandas?

risposta

0

Un modo per vettorizzare è accedere ai valori delle serie P1 e P2 indicizzando con una serie di etichette.

In [20]: df = X.reset_index() 

In [21]: mP1 = P1[df.P1].values 

In [22]: mP2 = P2[df.P2].values 

In [23]: mP1 
Out[23]: array([ 0.4, 0.4, 0.6, 0.6]) 

In [24]: mP2 
Out[24]: array([ 0.7, 0.3, 0.7, 0.3]) 

In [25]: mp = mP1 * mP2 

In [26]: mp 
Out[26]: array([ 0.28, 0.12, 0.42, 0.18]) 

In [27]: X.mul(mp, axis=0) 
Out[27]: 
     A  B 
P1 P2    
1 1 0.056 0.224 
    2 0.060 0.060 
2 1 0.378 0.042 
    2 0.162 0.018 

In [28]: X.mul(mp, axis=0).sum() 
Out[28]: 
A 0.656 
B 0.344 

In [29]: sum(
    sum(
    X.xs(i, level="P1")*P1[i] 
    for i in P1.index 
    ).xs(j)*P2[j] 
    for j in P2.index 
    ) 
Out[29]: 
A 0.656 
B 0.344 

(In alternativa, accedere ai valori di un MultiIndex senza ripristinare l'indice come segue.)

In [38]: P1[X.index.get_level_values("P1")].values 
Out[38]: array([ 0.4, 0.4, 0.6, 0.6])