Как в Pandas создать фрейм данных из количества элементов в столбце, разделенных запятыми?

В python3 и pandas у меня есть фреймворк, который содержит для каждой строки информацию о судебных разбирательствах.

В столбце «ном» указаны имена людей, в столбце «типо» - типы исков, всего два типа - INQ и AP.

А в колонке «Resumo» есть преступления, расследованные для судебного преследования. Но каждый судебный процесс может состоять из одного или нескольких преступлений. И преступления разделены ",":

Peculato,           Lavagem de Dinheiro
Corrupção passiva,  Ocultação de bens, Lavagem de dinheiro
Corrupção passiva,  Lavagem de dinheiro, Crimes Eleitorais
Crimes Eleitorais,  Lavagem de dinheiro
Peculato
Quadrilha ou Bando, Crimes da Lei de licitações, Peculato

Мне нужно посчитать:

For each name
Divided by INQ and AP processes
The appearance of each individual crime between ","

Возьмем пример выше столбца «resumo» и предположим, что все они относятся к человеку «Джон Доу».

Первые две строки относятся к типу AP, а остальные - к INQ, затем у Джона Доу:

1 AP for Peculato
2 AP for Lavagem de dinheiro
1 AP for Corrupção passiva
1 AP for Ocultação de bens

1 INQ for Corrupção passiva
2 INQ for Lavagem de dinheiro
2 INQ for Crimes Eleitorais
2 INQ for Peculato
1 INQ for Quadrilha ou Bando
1 INQ for Crimes da Lei de licitações

Образец строк выглядит как

df_selecao_atual[['tipo', 'resumo', 'nome']].head(5).to_dict()
{'tipo': {2: 'INQ', 3: 'AP', 4: 'INQ', 5: 'INQ', 6: 'AP'},
 'resumo': {2: 'Desvio de verbas públicas',
  3: 'Desvio de verbas públicas',
  4: nan,
  5: 'Prestação de contas rejeitada',
  6: 'Peculato, Gestão fraudulenta'},
 'nome': {2: 'CÉSAR MESSIAS',
  3: 'CÉSAR MESSIAS',
  4: 'FLAVIANO MELO',
  5: 'FLAVIANO MELO',
  6: 'FLAVIANO MELO'}}

В этой базе данных у меня уже был ответ, который очень хорошо сработал по этой ссылке: В пандах, как подсчитывать элементы между запятыми, разделяя типы столбцов?

Но теперь мне нужно не только показать на экране, но и создать фрейм данных. Нравится:

nome                tipo    resumo              count
Fulano de tal       INQ     Peculato            4
Fulano de tal       INQ     Ocultação de Bens   1
Fulano de tal       INQ     Corrupção ativa     2
Fulano de tal       INQ     Investigação Penal  3
Fulano de tal       AP      Peculato            1
Fulano de tal       AP      Corrupção passiva   2
Beltrano da Silva   INQ     Peculato            2
Beltrano da Silva   INQ     Lavagem de dinheiro 5
Beltrano da Silva   AP      Lavagem de dinheiro 1

Пожалуйста, кто-нибудь знает, как я могу создать этот фрейм данных?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
0
113
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете создать еще один DataFrame по столбцу splitresumo и добавить к исходному по join, затем для подсчета использовать groupby с size:

s = (df.pop('resumo').str.split(',', expand=True)
       .stack()
       .reset_index(level=1, drop=True)
       .rename('resumo'))


df = df.join(s).groupby(['nome','tipo','resumo']).size().reset_index(name='count')
print (df)
            nome tipo                         resumo  count
0  CÉSAR MESSIAS   AP      Desvio de verbas públicas      1
1  CÉSAR MESSIAS  INQ      Desvio de verbas públicas      1
2  FLAVIANO MELO   AP             Gestão fraudulenta      1
3  FLAVIANO MELO   AP                       Peculato      1
4  FLAVIANO MELO  INQ  Prestação de contas rejeitada      1

Если вы хотите использовать решение Counter с последним решением:

s = df.dropna().groupby(['nome', 'tipo']).resumo.agg(', '.join).str.split(', ').agg(Counter)
print (s)
nome           tipo
CÉSAR MESSIAS  AP              {'Desvio de verbas públicas': 1}
               INQ             {'Desvio de verbas públicas': 1}
FLAVIANO MELO  AP      {'Peculato': 1, 'Gestão fraudulenta': 1}
               INQ         {'Prestação de contas rejeitada': 1}
Name: resumo, dtype: object

df2 = (pd.DataFrame(s.values.tolist(), index=s.index)
         .stack()
         .astype(int)
         .reset_index(name='count')
         .rename(columns = {'level_2':'resumo'}))
print (df2)
            nome tipo                         resumo  count
0  CÉSAR MESSIAS   AP      Desvio de verbas públicas      1
1  CÉSAR MESSIAS  INQ      Desvio de verbas públicas      1
2  FLAVIANO MELO   AP             Gestão fraudulenta      1
3  FLAVIANO MELO   AP                       Peculato      1
4  FLAVIANO MELO  INQ  Prestação de contas rejeitada      1

Спасибо большое. Но у меня при его выполнении произошла ошибка. Я поставил это

Reinaldo Chaves 17.08.2018 17:07

Я очень прошу прощения, это была моя ошибка. Код работает сейчас

Reinaldo Chaves 17.08.2018 17:11

Еще раз спасибо @jezrael. Теперь я заметил небольшую проблему: скрипт различает строки, если раньше есть пробелы - например, «Corrupção ativa» и «Corrupção ativa».

Reinaldo Chaves 04.09.2018 23:42

Пожалуйста, есть ли способ убрать это пространство и правильно считать?

Reinaldo Chaves 04.09.2018 23:43

@ReinaldoChaves - Как работает изменение (df.pop('resumo').str.split(',', expand=True) на (df.pop('resumo').str.split(',\s*', expand=True) - разделение на , и ноль или более пробелов?

jezrael 05.09.2018 07:45

Практически та же логика, что и у Jez, измените вашу строку на list, затем отключите list, затем мы просто groupby и создадим счетчик

newdf=df.set_index(['nome','tipo'])['resumo'].str.split(',').apply(pd.Series).stack().to_frame('resumo').reset_index(level=[0,1])
newdf['count']=newdf.groupby(['nome','tipo','resumo'])['resumo'].transform('size')
newdf
Out[172]: 
            nome tipo                         resumo  count
0  CÉSAR MESSIAS  INQ      Desvio de verbas públicas      1
0  CÉSAR MESSIAS   AP      Desvio de verbas públicas      1
0  FLAVIANO MELO  INQ  Prestação de contas rejeitada      1
0  FLAVIANO MELO   AP                       Peculato      1
1  FLAVIANO MELO   AP             Gestão fraudulenta      1

Другие вопросы по теме