В 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
Пожалуйста, кто-нибудь знает, как я могу создать этот фрейм данных?






Вы можете создать еще один 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
Я очень прошу прощения, это была моя ошибка. Код работает сейчас
Еще раз спасибо @jezrael. Теперь я заметил небольшую проблему: скрипт различает строки, если раньше есть пробелы - например, «Corrupção ativa» и «Corrupção ativa».
Пожалуйста, есть ли способ убрать это пространство и правильно считать?
@ReinaldoChaves - Как работает изменение (df.pop('resumo').str.split(',', expand=True) на (df.pop('resumo').str.split(',\s*', expand=True) - разделение на , и ноль или более пробелов?
Практически та же логика, что и у 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
Спасибо большое. Но у меня при его выполнении произошла ошибка. Я поставил это