Панды: Top N и общая сумма за оставшиеся.Это для каждой из групп - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть фрейм данных со страной, регионом, городом, продуктом и продажами в $, ед.Мне нужно получить топ-3 продукта для каждой страны, региона, города и оставшегося товара в разделе «Прочее» с соответствующими продажами и единицами

Конечным результатом являются топ-3 продукта + «Прочее» для каждой комбинацииСтрана, Регион, Город

Country Region City Product Sales Val
Europe Italy Milan Ring 100 10 
Europe Italy Milan Book 300 5 
Europe Italy Milan Phone 1500 10 
Europe Italy Milan Car 200 5 
Europe Italy Milan Ring 100 10 
Europe Italy Milan Pen 8200 5 

Результаты для топ-3:

Country Region City Product Sales Val
Europe Italy Milan Pen 8200 5 
Europe Italy Milan Phone 1500 10 
Europe Italy Milan Book 300 5 
Europe Italy Milan Other 400 25

1 Ответ

0 голосов
/ 27 ноября 2018

Сначала необходимо создать индекс по умолчанию reset_index:

df = df.reset_index(drop=True)

Затем выполнить сортировку по столбцу Sales по sort_values с GroupBy.head получить топ3 строки по группам:

cols = ['Country','Region', 'City']
df1 = df.sort_values('Sales', ascending=False).groupby(cols).head(3)
print (df1)
  Country Region   City Product  Sales  Val
5  Europe  Italy  Milan     Pen   8200    5
2  Europe  Italy  Milan   Phone   1500   10
1  Europe  Italy  Milan    Book    300    5

Затем отфильтровать строки, используемые для top3 и агрегата sum:

df2 = df.loc[df.index.difference(df1.index)]
df2 = df2.groupby(cols, as_index=False).sum().assign(Product='Other')
print (df2)
  Country Region   City  Sales  Val Product
0  Europe  Italy  Milan    400   25   Other

Последнее объединение по concat:

df = pd.concat([df1, df2]).sort_values(cols).reset_index(drop=True)
print (df)
    City Country Product Region  Sales  Val
0  Milan  Europe     Pen  Italy   8200    5
1  Milan  Europe   Phone  Italy   1500   10
2  Milan  Europe    Book  Italy    300    5
3  Milan  Europe   Other  Italy    400   25

Другое решение:

print (df)
   Country Region   City Product  Sales  Val
0   Europe  Italy  Milan    Ring    100   10
1   Europe  Italy  Milan    Book    300    5
2   Europe  Italy  Milan   Phone   1500   10
3   Europe  Italy  Milan     Car    200    5
4   Europe  Italy  Milan    Ring    100   10
5   Europe  Italy   Rome     Pen   8200    5
6   Europe  Italy   Rome    Ring    100   10
7   Europe  Italy   Rome    Book    300    5
8   Europe  Italy   Rome   Phone   1500   10
9   Europe  Italy   Rome     Car    200    5
10  Europe  Italy   Rome    Ring    100   10
11  Europe  Italy   Rome  Pencil   8100    5

Идея состоит в сортировке значений по Sales и создании столбца счетчика для групп по cumcount и замените значения Product на Other:

cols = ['Country','Region', 'City']
df['g'] = df.sort_values('Sales', ascending=False).groupby(cols).cumcount()
df['Product'] = np.where(df['g'] >= 3 , 'Other', df['Product'])
print (df)
   Country Region   City Product  Sales  Val  g
0   Europe  Italy  Milan   Other    100   10  3
1   Europe  Italy  Milan    Book    300    5  1
2   Europe  Italy  Milan   Phone   1500   10  0
3   Europe  Italy  Milan     Car    200    5  2
4   Europe  Italy  Milan   Other    100   10  3
5   Europe  Italy   Rome     Pen   8200    5  0
6   Europe  Italy   Rome   Other    100   10  3
7   Europe  Italy   Rome   Other    300    5  3
8   Europe  Italy   Rome   Phone   1500   10  2
9   Europe  Italy   Rome   Other    200    5  3
10  Europe  Italy   Rome   Other    100   10  3
11  Europe  Italy   Rome  Pencil   8100    5  1

Затем агрегируйте на sum:

df2 = (df.groupby(cols + ['Product'], as_index=False).sum()
         .sort_values(cols + ['g'])
         .drop('g', axis=1)
         .reset_index(drop=True))
print (df2)
  Country Region   City Product  Sales  Val
0  Europe  Italy  Milan   Phone   1500   10
1  Europe  Italy  Milan    Book    300    5
2  Europe  Italy  Milan     Car    200    5
3  Europe  Italy  Milan   Other    200   20
4  Europe  Italy   Rome     Pen   8200    5
5  Europe  Italy   Rome  Pencil   8100    5
6  Europe  Italy   Rome   Phone   1500   10
7  Europe  Italy   Rome   Other    700   30
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...