Проверка распределения и количества значений столбца на основе типов групп в другом столбце в Python

#python #pandas

#python #pandas

Вопрос:

У меня есть фрейм данных, подобный этому:

    Data_Entry   Type
0           1   Blue
1          10  Green
2           5  Green
3           2   Blue
4          12   Blue
5           2  Green
6           2    Red
7          50   Blue
8          32   Blue
9          76    Red
10         75    Red
11         12   Blue
  

Я хочу провести некоторый анализ вокруг этого в Python, который дал бы мне:

  1. Распределение в процентилях для каждого типа
  2. Количество значений каждого типа в пределах диапазона

Так, например, для типа BLUE я бы получил значение, равное:

 Value counts between 1-5 :  2
Value counts between 5-10:  0
Value counts between 10-15: 2
Value counts between 15-20: 0
Value counts between 20-25: 0
Value counts between 25-30: 0
Value counts between 30-35: 1
Value counts between 35-40: 0
Value counts between 40-45: 0
Value counts between 45-50: 0
Value counts between 50-55: 1
  

И я также хотел бы получить распределение в процентилях для каждого типа отдельно.

Вот что я пробовал до сих пор:

  1. Процентильное расстояние:

На данный момент я использую следующий код для разделения каждого типа в его собственном фрейме данных, а затем применяю к нему функцию квантиля:

 df_blue=df.loc[df['Type'] == 'Blue']

p_30_blue=df_blue.Data_Entry.quantile(0.30)
p_40_blue=df_blue.Data_Entry.quantile(0.40)
p_50_blue=df_blue.Data_Entry.quantile(0.50)
p_60_blue=df_blue.Data_Entry.quantile(0.60)
p_80_blue=df_blue.Data_Entry.quantile(0.80)
  
  1. Подсчет значений:

Я использовал встроенные в pythons функции sql:

 import pandasql as ps

    q= """SELECT Type,CASE 
             WHEN Data_entry <= 10 THEN '1-10' 
             WHEN Data_entry <= 50 and Data_entry >= 10 THEN '11-50' 
             WHEN Data_entry >= 50 and Data_entry <= 100 THEN '50-100' 
             ELSE '>=100' 
           END AS counts, 
           COUNT(*) AS n
    FROM df
    GROUP BY Type,CASE WHEN Data_entry <= 10 THEN '1-10' 
             WHEN Data_entry <= 50 and Data_entry >= 10 THEN '11-50' 
             WHEN Data_entry >= 50 and Data_entry <= 100 THEN '50-100' 
             ELSE '>=100' 
           END """
    
    result=ps.sqldf(q, locals())
  

Что дало мне:

     Type counts  n
0   Blue   1-10  1
1   Blue  11-50  5
2  Green   1-10  1
3  Green  11-50  2
4    Red  11-50  1
5    Red  >=100  2
  

Есть ли более эффективный способ сделать это?

Комментарии:

1. Что вы уже пробовали? Вам нужно посмотреть, как разделить ваш столбец, затем отфильтровать и посчитать количество записей.

2. @malik надеюсь, вы понимаете, SO — это не сервис для написания кода, и вам нужно показать, что вы прилагаете усилия для решения проблемы, чтобы избежать закрытия вопроса.

3. здравствуйте, я добавил код, который я использую до сих пор, чтобы показать, что я пробовал.

Ответ №1:

Что-то с pd.cut для классификации values и groupby ?

 df.groupby([pd.cut(df.Data_Entry, bins=np.arange(0,100,5)), 'Type']).size().unstack('Type')
  

Вывод:

 Type        Blue  Green  Red
Data_Entry                  
(0, 5]         2      2    1
(5, 10]        0      1    0
(10, 15]       2      0    0
(15, 20]       0      0    0
(20, 25]       0      0    0
(25, 30]       0      0    0
(30, 35]       1      0    0
(35, 40]       0      0    0
(40, 45]       0      0    0
(45, 50]       1      0    0
(50, 55]       0      0    0
(55, 60]       0      0    0
(60, 65]       0      0    0
(65, 70]       0      0    0
(70, 75]       0      0    1
(75, 80]       0      0    1
(80, 85]       0      0    0
(85, 90]       0      0    0
(90, 95]       0      0    0
  

Ответ №2:

Создайте подмножества из вашего фрейма данных, которые соответствуют вашему условию. Например, для данных со значениями от 1 до 5 выполните df[df['Data_Entry'] >= 1][df['Data_Entry'] <= 5] . Тогда вы могли бы считать следующим образом: df[df['Data_Entry'] >= 1][df['Data_Entry'] <= 5].value_counts() . Возвращаемое значение может быть преобразовано в словарь: dict(df[df['Data_Entry'] >= 1][df['Data_Entry'] <= 5].value_counts()) . Оттуда также должно быть легко вычислить проценты