Как рассчитать процент элементов заказа во всех заказах в Pandas

#python #pandas

#python #pandas

Вопрос:

У меня возникают трудности с вычислением того, сколько элементов присутствует во всех портфелях заказов в процентах? Предметы — это игрушки, которые обычно покупают люди: медведь, кролик, лось, собака, лошадь, кошка, мышь, свинья, курица, орел, енот, дельфин, акула и кит.

У меня есть order_portfolio_id, который представляет человека, покупающего игрушки, и у меня есть столбцы position_X, где X — номер позиции заказанного товара, всего 8 позиций. Человек, заказывающий игрушки, никогда не будет покупать одну и ту же игрушку дважды, поэтому товары никогда не повторяются в одном портфеле / строке. Пожалуйста, обратите внимание, что мой исходный фрейм данных содержит NaN, поэтому я также включил их сюда.

 >>> import pandas as pd
>>> from numpy import nan
>>> 
>>> data = pd.DataFrame({'order_portfolio_num': [1,2,3,4,5,6,7,8],
...                     'order_position_1':['dog', 'horse', 'cat','shark', 'dog', 'rabbit', 'rabbit', 'cat'],
...                     'order_position_2':['mouse', 'bear', 'dog', 'dolphin', 'cat', 'bear', 'eagle', 'shark'],
...                     'order_position_3':['bear', 'dog', 'raccoon', 'dog', 'whale', 'mouse', 'cat', 'moose'],
...                     'order_position_4':['dolphin', 'cat', 'chicken', nan, 'horse', 'pig', 'dog', 'chicken'],
...                     'order_position_5':['pig', 'chicken', 'eagle', nan, 'bear', 'raccoon', 'whale', nan], 
...                     'order_position_6':[nan, 'whale', nan, nan, 'eagle', 'moose', nan, nan],
...                     'order_position_7':[nan, 'dolphin', nan, nan, nan, 'chicken', nan, nan]})
>>> 
>>> data
   order_portfolio_num order_position_1 order_position_2 order_position_3 order_position_4 order_position_5 order_position_6 order_position_7
0                    1              dog            mouse             bear          dolphin              pig              NaN              NaN
1                    2            horse             bear              dog              cat          chicken            whale          dolphin
2                    3              cat              dog          raccoon          chicken            eagle              NaN              NaN
3                    4            shark          dolphin              dog              NaN              NaN              NaN              NaN
4                    5              dog              cat            whale            horse             bear            eagle              NaN
5                    6           rabbit             bear            mouse              pig          raccoon            moose          chicken
6                    7           rabbit            eagle              cat              dog            whale              NaN              NaN
7                    8              cat            shark            moose          chicken              NaN              NaN              NaN
 

Я хотел бы рассчитать 5 самых распространенных игрушек, заказанных во всех портфелях, в процентах. Например, если у меня есть 10 папок order_port, и игрушечный медведь присутствует в 4 из них, игрушечный медведь будет иметь значение 40%. Моя цель — иметь что-то похожее на это:

 toy      percent
dog        60%
cat        48%
mouse      36%
bear       28%
shark      19%
 

Я попытался просуммировать все игрушки во фрейме данных, но я получил количество вхождений всех игрушек во всех портфелях, и я не уверен, как точно рассчитать процент от этого (какое значение представляет 100% значение?), И если это даже то, что я ищу, поскольку этодаст мне процент встречаемости всех игрушек, а не портфелей. Поэтому я не уверен, как поступить. Это то, что я пробовал:

 >>> cols = ['order_position_1', 'order_position_2', 'order_position_3', 'order_position_4',
...        'order_position_5', 'order_position_6', 'order_position_7'] 
>>> 
>>> position_values = data[cols].melt().groupby('value').size().reset_index(name='count')
>>> 
>>> position_values.sort_values(by = 'count', ascending = False)
      value  count
3       dog      6
1       cat      5
0      bear      4
2   chicken      4
4   dolphin      3
5     eagle      3
13    whale      3
6     horse      2
7     moose      2
8     mouse      2
9       pig      2
10   rabbit      2
11  raccoon      2
12    shark      2
 

Есть идеи?

Ответ №1:

Используйте DataFrame.melt с Series.value_counts и делите на исходное количество строк:

 df = data.melt('order_portfolio_num')['value'].value_counts().div(len(data)).mul(100).head()
print (df)
dog        75.0
cat        62.5
bear       50.0
chicken    50.0
dolphin    37.5
Name: value, dtype: float64
 

Ответ №2:

Это общая идея:

  1. Сначала получите название всех игрушек
  2. Проверьте для каждой игрушки, находится ли она в строке, и сохраните это количество
  3. Получить частоту
 unique_values = df.drop(columns = "order_portfolio_num").stack().unique()
count = pd.Series([(df == x).any(1).sum() for x in unique_values], unique_values)
frec = count / df["order_portfolio_num"].size() * 100

print(frec.head())
dog        75.0
mouse      25.0
bear       50.0
dolphin    37.5
pig        25.0
 

Документация

Ответ №3:

разделите каждое значение на количество портфелей заказов (N)

 position_values['percent']=position_values['count']/data['order_portfolio_num'].count()
 

а затем отсортировать и возглавить