How can I convert non-zero entries in Pandas to dict with list?

Question:

Assume now I have a mask

mask = df.DataFrame([[0, 0, 1], [1, 1, 0], [0, 0, 1]])

Actullay, mask is

    0  1  2
0   0  0  1
1   1  1  0
2   0  0  1

Besides, I have a score matrix like

score = df.DataFrame([[0.5, 0.3, 0.2], [0.1, 0.9, 0.7], [0.5, 0.4, 0.8]])

I.e.

    0    1    2
0   0.5  0.3  0.2
1   0.1  0.9  0.7
2   0.5  0.4  0.8

I only want to retain the entries of score with “true” in mask, i.e. the result should be

    0    1    2
0   0    0    0.2
1   0.1  0.9  0
2   0    0    0.8

Finally, I need to convert result to dict with list like

result = {0: {2: 0.2}, 1: {0: 0.1, 1: 0.9}, 2: {2: 0.8}}

How can I do in a Pythonic way? Thank you!

Asked By: Lizhi Liu

||

Answers:

Use DataFrame.where with casting 0,1 mask to boolean:

print (score.where(mask.astype(bool), 0))
     0    1    2
0  0.0  0.0  0.2
1  0.1  0.9  0.0
2  0.0  0.0  0.8

Then convert to dictionary and remove 0 values in nested dictionaries:

d = score.where(mask.astype(bool), 0).to_dict(orient='index')

d = {k:{k1:v1 for k1, v1 in v.items() if v1 != 0} for k, v in d.items()}
print (d)
{0: {2: 0.2}, 1: {0: 0.1, 1: 0.9}, 2: {2: 0.8}}

Another idea with reshape by DataFrame.stack and replace not matched values to NaN:

s = score.where(mask.astype(bool)).stack()
d = {level: s.xs(level).to_dict() for level in s.index.levels[0]}
print (d)
{0: {2: 0.2}, 1: {0: 0.1, 1: 0.9}, 2: {2: 0.8}}
Answered By: jezrael

use apply and to_dict

 df1:

     0    1    2
0  0.0  0.0  0.2
1  0.1  0.9  0.0
2  0.0  0.0  0.8

df1.apply(lambda ss:ss[ss.ne(0)].to_dict(),axis=1).to_dict()

output:

{0: {'2': 0.2}, 1: {'0': 0.1, '1': 0.9}, 2: {'2': 0.8}}
Answered By: G.G
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.