Выбор верхнего% строк в pandas - PullRequest
0 голосов
/ 10 июля 2020

У меня есть образец фрейма данных, как показано ниже (фактический набор данных составляет примерно 300 тыс. Записей):


        user_id   revenue  
 ----- --------- --------- 
    0       234       100  
    1      2873       200  
    2       827       489  
    3        12       237  
    4      8942     28934  
  ...       ...       ...  
   96       498    892384  
   97      2345        92  
   98       239      2803  
   99      4985     98332  
  100       947      4588  

, который отображает доход, полученный пользователями. Я хотел бы выбрать строки, в которых генерируются верхние 20% дохода (следовательно, получают верхние 20% пользователей, генерирующих доход).

Наиболее близким мне методом является вычисление общего количества пользователи, отработав 20% этого, сортируя фрейм данных с помощью sort_values(), а затем используя head() или nlargest(), но я хотел бы знать, есть ли более простой и элегантный способ.

Можно кто-нибудь предлагает способ для этого? Спасибо!

Ответы [ 4 ]

1 голос
/ 11 июля 2020

Предположим, у вас есть фрейм данных df:

user_id revenue
234     21  
2873    20  
827     23  
12      23  
8942    28  
498     22  
2345    20  
239     24  
4985    21  
947     25

Я выровнял распределение доходов, чтобы показать идею. Теперь вычисляем пошагово:

df = pd.read_clipboard()
df = df.sort_values(by = 'revenue', ascending = False)
df['revenue_cum'] = df['revenue'].cumsum()
df['%revenue_cum'] = df['revenue_cum']/df['revenue'].sum()
df

результат:

   user_id  revenue  revenue_cum  %revenue_cum
4     8942       28           28      0.123348
9      947       25           53      0.233480
7      239       24           77      0.339207
2      827       23          100      0.440529
3       12       23          123      0.541850
5      498       22          145      0.638767
0      234       21          166      0.731278
8     4985       21          187      0.823789
1     2873       20          207      0.911894
6     2345       20          227      1.000000

Только 2 ведущих пользователя приносят 23,3% от общего дохода.

0 голосов
/ 11 июля 2020

Я предполагаю, что вы ищете пользователей, приносящих совокупный доход 20%. Вот функция, которая поможет вам получить ожидаемый результат и даже больше. Просто укажите свой фрейм данных, название столбца дохода и n_percent, который вы ищете:

import pandas as pd

def n_percent_revenue_generating_users(df, col, n_percent):
    df.sort_values(by=[col], ascending=False, inplace=True)
    df[f'{col}_cs'] = df[col].cumsum()
    df[f'{col}_csp'] = 100*df[f'{col}_cs']/df[col].sum()
    df_ = df[df[f'{col}_csp'] > n_percent]
    index_nearest = (df_[f'{col}_csp']-n_percent).abs().idxmin()
    threshold_revenue = df_.loc[index_nearest, col]
    output = df[df[col] >= threshold_revenue].drop(columns=[f'{col}_cs', f'{col}_csp'])
    
    return output
    
n_percent_revenue_generating_users(df, 'revenue', 20) 
0 голосов
/ 10 июля 2020

Обычно я нахожу полезным использовать sort_values, чтобы увидеть совокупный эффект каждой строки, а затем сохранить строки до некоторого порога:

# Sort values from highest to lowest:
df = df.sort_values(by='revenue', ascending=False)

# Add a column with aggregated effect of the row:
df['cumulative_percentage'] = 100*df.revenue.cumsum()/df.revenue.sum()

# Define the threshold I need to analyze and keep those rows:
min_threshold = 30
top_percent = df.loc[df['cumulative_percentage'] <= min_threshold]

Исходный df будет хорошо отсортирован с четким указанием верхние вспомогательные строки и созданный df 'top_percent' будут содержать строки, которые необходимо проанализировать в частности.

0 голосов
/ 10 июля 2020

Это похоже на df.quantile, из pandas документации если вы ищете верхние 20%, все, что вам нужно сделать, это передать правильное значение квантиля, которое вы желаете.

Пример случая из вашего набора данных:

import pandas as pd
import numpy as np
df = pd.DataFrame({'user_id':[234,2873,827,12,8942],
                           'revenue':[100,200,489,237,28934]})
df.quantile([0.8,1],interpolation='nearest')

Это выведет две верхние строки в value:

     user_id  revenue
0.8     2873      489
1.0     8942    28934
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...