#python #python-3.x #pandas
#python #python-3.x #pandas
Вопрос:
Я пытаюсь объединить значение ‘count’ в верхнюю строку моего фрейма данных.
Вот пример моих исходных данных:
Name,IP,Application,Count
Tom,100.100.100,MsWord,5
Tom,100.100.100,Excel,10
Fred,200.200.200,Python,1
Fred,200.200.200,MsWord,5
df = pd.DataFrame(data, columns=['Name', 'IP', 'Application', 'Count'])
df_new = df.groupby(['Name', 'IP'])['Count'].apply(lambda x:x.astype(int).sum())
Если я печатаю df_new, это приводит к следующему результату:
Name,IP,Application,Count
Tom,100.100.100,MsWord,15
................Excel,15
Fred,200.200.200,MsWord,6
................Python,6
Как вы можете видеть, количество было рассчитано правильно, для Tom оно добавило 5 к 10 и получило результат 15. Однако это отображается в каждой строке группы.
Есть ли какой-либо способ получить выходные данные следующим образом — таким образом, счетчик находится только в первой строке группы:
Name,IP,Application,Count
Tom,100.100.100,MsWord,15
.................Excel
Fred,200.200.200,MsWord,6
.................Python
Можно ли как-нибудь записать dt_new
в файл в этом удобном формате?
Я хотел бы, чтобы выходные данные выглядели как таблица и были почти похожи на лист Excel со объединенными ячейками.
Я пытался, dt_new.to.csv('path')
но это удаляет хорошее форматирование, которое я вижу при выводе dt
на консоль.
Комментарии:
1. По сути, когда вы говорите
dt
иdt_new
, вы имеете в видуdf
иdf_new
соответственно?2. CSV — это конструкция для хранения текста, разделенного запятыми. Даже если вы создадите электронную таблицу в Excel, а затем сохраните ее как CSV, все форматирование будет удалено, поскольку csv не поддерживает информацию о форматировании. Вы можете использовать to_html() в записной книжке jupyter для создания красивых форматов таблиц. В противном случае вам нужно будет найти другую технологию
3. Также ваш вывод не соответствует вашему вводу. Результатом
df.groupby(['name', 'ip', 'app'])['cnt'].apply(lambda x: x.astype(int).sum())
будет Tom, 100, MSWord, 10 в первой строке. Возможно, вы имели в видуdf.groupby(['name', 'ip'])['cnt'].apply(lambda x: x.astype(int).sum())
4. @WoodyPride Спасибо за ваш ответ, html звучит как хорошее предложение. Вы правы насчет инструкции df.groupby. Сейчас я обновлю сообщение
Ответ №1:
Обрабатывать фрейм данных и предоставлять в нем сводные строки довольно сложно. Как правило, фрейм данных позволяет получать результаты, которые не зависят от позиции, такие как последний элемент в группе. Это можно сделать, но лучше разделить эти проблемы.
import pandas as pd
from StringIO import StringIO
data = StringIO("""Name,IP,Application,Count
Tom,100.100.100,MsWord,5
Tom,100.100.100,Excel,10
Fred,200.200.200,Python,1
Fred,200.200.200,MsWord,5""")
#df = pd.DataFrame(data, columns=['Name', 'IP', 'Application', 'Count'])
#df_new = df.groupby(['Name', 'IP', 'Application'])['Count'].apply(lambda x:x.astype(int).sum())
df = pd.read_csv(data)
new_df = df.groupby(['Name', 'IP']).sum()
# reset the two levels of columns resulting from the groupby()
new_df.reset_index(inplace=True)
df.set_index(['Name', 'IP'], inplace=True)
new_df.set_index(['Name', 'IP'], inplace=True)
print(df)
Application Count
Name IP
Tom 100.100.100 MsWord 5
100.100.100 Excel 10
Fred 200.200.200 Python 1
200.200.200 MsWord 5
print(new_df)
Count
Name IP
Fred 200.200.200 6
Tom 100.100.100 15
print(new_df.join(df, lsuffix='_lsuffix', rsuffix='_rsuffix'))
Count_lsuffix Application Count_rsuffix
Name IP
Fred 200.200.200 6 Python 1
200.200.200 6 MsWord 5
Tom 100.100.100 15 MsWord 5
100.100.100 15 Excel 10
Отсюда вы можете использовать multiindex для доступа к сумме групп.