My DataFrame represents attributes in each column and yes/no-values in each row if applicable:
d_att = { 'attribute1': ['yes', 'yes', 'no'],
'attribute2': ['no', 'yes', 'no'],
'attribute3': ['no', 'no', 'yes'] }
df_att = pd.DataFrame(data=d_att)
df_att
attribute1 attribute2 attribute3
0 yes no no
1 yes yes no
2 no no yes
Now I need to calculate the likelihood of each combination of attributes, e.g. if attribute1 is yes then the likelihood of attribute2 also being yes is 0.5.
I'm aiming for a DataFrame like this:
attribute1 attribute2 attribute3
attribute1 1.0 0.5 0.0
attribute2 1.0 1.0 0.0
attribute3 0.0 0.0 1.0
So far I started by replacing the yes/no-values with integers (1/0):
df_att_int = df_att.replace({'no': 0, 'yes': 1})
df_att_int
attribute1 attribute2 attribute3
0 1 0 0
1 1 1 0
2 0 0 1
Then I defined a method that loops over each column, filters the DataFrame for rows with value 1 in the current column, calculates the sum for each column in the filtered DataFrame, and divides the sum(s) by the number of filtered rows (=sum) for the current column:
def combination_likelihood(df):
df_dict = {}
for column in df.columns:
col_sum = df[df[column]==1].sum()
divisor = col_sum[column]
df_dict[column] = col_sum.apply(lambda x: x/divisor)
return pd.DataFrame(data=df_dict).T
Applying the method on my df_att_int-DataFrame delivers the expected result:
df_att_comb_like = combination_likelihood(df_att_int)
df_att_comb_like
attribute1 attribute2 attribute3
attribute1 1.0 0.5 0.0
attribute2 1.0 1.0 0.0
attribute3 0.0 0.0 1.0
However, if the attribute/column-names are not in alphabetical order, rows will be sorted by label and the characteristical pattern needed for insightful plots will be lost, for example resulting in following structure:
attribute2 attribute3 attribute1
attribute1 0.5 0.0 1.0
attribute2 1.0 0.0 1.0
attribute3 0.0 1.0 0.0
Ultimately, I want to plot out the result as a heatmap:
import seaborn as sns
sns.heatmap(df_att_comb_like)

Is there an easier, more elegant way to construct the likelihood-DataFrame and preserving the same order for columns and row-labels? Any help would be greatly appreciated!