разбить значения словаря на отдельные столбцы панды в фрейме данных - сделать их фиктивными - PullRequest
3 голосов
/ 04 октября 2019

Скажем, у нас есть кадр данных в этом формате:

id  properties
0   {"cat1":["p1","p2","p4"],"cat2":["p5", "p6"]}
1   {"cat1":["p3"],"cat2":["p7"]}

Как мы можем преобразовать его в этот формат?

id  p1    p2    p3    p4    p5    p6    p7
0   True  True  False True  True  True  False
1   False False True  False False False True

Имейте в виду, что типом значений в каждой ячейке является строка. Он имеет только две категории: cat1 и cat2

Ответы [ 4 ]

3 голосов
/ 04 октября 2019

Использование itertools.chain.from_iterable и str.get_dummies

from itertools import chain

df.properties.apply(lambda s: ','.join(chain.from_iterable(s.values())))\
             .str.get_dummies(sep=',')\
             .astype(bool)

      p1     p2     p3     p4     p5     p6     p7
0   True   True  False   True   True   True  False
1  False  False   True  False  False  False   True
2 голосов
/ 04 октября 2019

Я буду использовать get_dummies

df.properties.map(lambda x : ','.join(sum(x.values(),[]))).str.get_dummies(',').astype(bool)
      p1     p2     p3     p4     p5     p6     p7
0   True   True  False   True   True   True  False
1  False  False   True  False  False  False   True
2 голосов
/ 04 октября 2019

Использование stack + explode + get_dummies

u = pd.DataFrame(df['properties'].tolist())

u.stack().explode().add(',').sum(level=0).str.get_dummies(',')

   p1  p2  p3  p4  p5  p6  p7
0   1   1   0   1   1   1   0
1   0   0   1   0   0   0   1
1 голос
/ 04 октября 2019

Установить_индексом id. Как вы сказали, каждая ячейка является строкой, поэтому вам нужно преобразовать df.properties из строки dict в dict, используя ast.literal_eval. Затем, используя метод str, получите cat1 и cat2 и объедините их списки и explode их в строки и присвойте результат s. Наконец, вызовите pd.get_dummies на s с опцией dtype=bool и вызовите max на уровне = 0

import ast

df1 = df.set_index('id')
df1.properties = df1.properties.map(ast.literal_eval)
s = (df1.properties.str['cat1'] + df1.properties.str['cat2']).explode()
pd.get_dummies(s, dtype=bool).max(level=0)

Out[1035]:
       p1     p2     p3     p4     p5     p6     p7
id
0   True   True   False  True   True   True   False
1   False  False  True   False  False  False  True
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...