хранить только ключи без значений None в словаре из групп панд

1
>>> df = pd.DataFrame({'a': [1,1,1,2,2,3,3,3,3,4,4,5,5], 
'b': [0,1,1,0,1,0,0,1,4,1,0,3,0], 
'v': [2,4,3,7,6,5,9,3,2,4,5,2,3]})
>>> df
    a  b  v
0   1  0  2
1   1  1  4
2   1  1  3
3   2  0  7
4   2  1  6
5   3  0  5
6   3  0  9
7   3  1  3
8   3  4  2
9   4  1  4
10  4  0  5
11  5  3  2
12  5  0  3

>>> df.groupby(by =['a', 'b']).v.apply(list).unstack().to_dict('index')
{1: {0: [2], 1: [4, 3], 3: None, 4: None}, 2: {0: [7], 1: [6], 3: None, 4: 
None}, 3: {0: [5, 9], 1: [3], 3: None, 4: [2]}, 4: {0: [5], 1: [4], 3: None, 4: 
None}, 5: {0: [3], 1: None, 3: [2], 4: None}}

Как можно избежать ключей с значениями None в выходном словаре? В текущем состоянии мой словарь заканчивается в 20 раз больше, чем нужно с помощью необходимых клавиш.

Теги:
pandas

3 ответа

2
Лучший ответ

Используя ту же идею, просто нужно to_dict дважды

df.groupby(by =['a', 'b']).v.apply(list).groupby(level=0).agg(lambda x : x.reset_index(level=0,drop=True).to_dict()).to_dict()
Out[1092]: 
{1: {0: [2], 1: [4, 3]},
 2: {0: [7], 1: [6]},
 3: {0: [5, 9], 1: [3], 4: [2]},
 4: {0: [5], 1: [4]},
 5: {0: [3], 3: [2]}}
2

groupby

{k: d.xs(k).to_dict()
 for k, d in df.groupby(by =['a', 'b']).v.apply(list).groupby(level=0)}

{1: {0: [2], 1: [4, 3]},
 2: {0: [7], 1: [6]},
 3: {0: [5, 9], 1: [3], 4: [2]},
 4: {0: [5], 1: [4]},
 5: {0: [3], 3: [2]}}

defaultdict

from collections import defaultdict

d = defaultdict(lambda:defaultdict(list))

for _, a, b, v in df.itertuples():
  d[a][b].append(v)

d

defaultdict(<function __main__.<lambda>>,
            {1: defaultdict(list, {0: [2], 1: [4, 3]}),
             2: defaultdict(list, {0: [7], 1: [6]}),
             3: defaultdict(list, {0: [5, 9], 1: [3], 4: [2]}),
             4: defaultdict(list, {0: [5], 1: [4]}),
             5: defaultdict(list, {0: [3], 3: [2]})})
2
d = df.groupby(by =['a', 'b']).v.apply(list).unstack().to_dict('index')
d = {k: {kk: vv for kk, vv in v.items() if vv is not None} for k, v in d.items()}

# d == {1: {0: [2], 1: [4, 3]}, 2: {0: [7], 1: [6]}, 3: {0: [5, 9], 1: [3], 4: [2]}, 4: {0: [5], 1: [4]}, 5: {0: [3], 3: [2]}}

Вы также можете сделать это в одной строке, если вы замените d во второй строке своей цепочкой df.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню