Я работаю в Pandas 0.23, и у меня есть столбец массива и логический столбец. Я хотел бы сгруппировать логическое значение и каждый отдельный элемент в массиве, чтобы найти истинные и ложные значения для каждого элемента.

Пример данных:

a = pd.DataFrame([
  {'vals': ['a,b,c'], 'succeeded': True},
  {'vals': ['a,b'], 'succeeded': False},
  {'vals': ['c'], 'succeeded': True},
  {'vals': ['b,d'], 'succeeded': False},
])

Пожеланная выходная мощность:

      succeeded_t     succeeded_f
a     1               1
b     1               2
c     2               0
d     0               1

Как лучше всего это сделать? Нужно ли мне сначала «разбить» элементы массива на строки, а затем сгруппировать?

0
Richard 17 Сен 2018 в 19:48

2 ответа

Лучший ответ

Вам может потребоваться сгладить список, затем использовать crosstab, также ваш список не является списком, это один список элементов со строкой, вам нужно сначала разделить его

a.vals=a.vals.map(lambda x : x[0].split(','))
newdf=pd.DataFrame({'succeeded':a['succeeded'].reindex(a.index.repeat(a.vals.str.len())),
                    'vals':np.concatenate(a['vals'].values)})
pd.crosstab(newdf['vals'],newdf['succeeded'])
Out[457]: 
succeeded  False  True 
vals                   
a              1      1
b              2      1
c              0      2
d              1      0
2
YOBEN_S 17 Сен 2018 в 17:12

Возможно, вы сможете сделать это за один раз, но просто подмножество двух групп и использование str.get_dummies для каждого подмножества, а затем объединение результатов

import pandas as pd

pd.concat([a[a.succeeded].vals.str.get_dummies(sep=',').sum().to_frame('succeeded_t'),
           a[~a.succeeded].vals.str.get_dummies(sep=',').sum().to_frame('succeeded_f')], 
          axis=1, sort=True).fillna(0)

Выход:

   succeeded_t  succeeded_f
a          1.0          1.0
b          1.0          2.0
c          2.0          0.0
d          0.0          1.0

Альтернативно

Если у вас будет много столбцов на выходе, которые вы не хотите объединять вручную:

(a.set_index('succeeded')
  .vals.str.get_dummies(sep=',')
  .groupby(level=0).sum().T
  .rename_axis(None, axis=1))

Выход:

   False  True 
a      1      1
b      2      1
c      0      2
d      1      0
2
ALollz 17 Сен 2018 в 17:09