Как мне получить совокупный процент для двух объединенных кодов, обозначенных значением в фрейме данных pandas

#python #pandas #string #algorithm #percentage

#python #pandas #строка #алгоритм #процент

Вопрос:

я новичок в Python и пытаюсь понять манипулирование данными

 df
Alpha               AlphaComboCount
12-99                   8039
22-99                   1792
12-99,138-99            1776
12-45,138-45            1585
21-99                   1225
123-99                  1145
121-99                  1102
21-581                  1000
121-99,22-99             909
32-99                    814
21-141                   75
12-581,12-99             711
347-99                   685
2089-281                 685
123-49,121-29,22-79      626
121-99,123-99,22-99      4
  

Как вы можете видеть выше, есть два столбца. Альфа — это строка, состоящая из объединения 2 кодов, разделенных символом ‘-‘. Моя цель — найти совокупный процент от alphacombocount по первому коду.
Например:

где имеется 21 подкод-

 Alpha   AlphaComboCount  Percent
21-99   1225             53%
21-141    75             3.2%
21-581  1000            43.3%
  

Цель, как вы видите выше, состоит в том, чтобы получить соответствующий процент. поскольку общее объединение здесь составляет 2300 из 21 подкода.

Где это становится более сложным, так это для комбинированных кодов:

    123-49,121-29,22-79       626  99%
    121-99,123-99,22-99      4   0.6%
  

Как вы видите выше, все первые вложенные коды одинаковы, но переставлены. Это также допустимый случай для получения процентных значений. При условии, что комбинация совпадает с первым подкодом перед ‘-‘. Как я могу сделать это, чтобы получить процентные значения для всех альфа-комбинаций? существует ли алгоритм для этого?

Ответ №1:

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

 # separate the codes
tmp = df.assign(FirstCode=df.Alpha.str.split(','))

# extract the first code
tmp['FirstCode'] = [tuple(sorted(set(x.split('-')[0] for x in cell)))
                        for cell in tmp.FirstCode]

# sum per each first codes with groupby
sum_per_code = tmp['AlphaComboCount'].groupby(tmp['FirstCode']).transform('sum')

# percentage is just a simple division
tmp['Percent'] = tmp['AlphaComboCount']/sum_per_code

# let's print the output:
print(tmp.sort_values('FirstCode'))
  

Вывод:

                   Alpha  AlphaComboCount       FirstCode   Percent
0                 12-99             8039           (12,)  0.918743
11         12-581,12-99              711           (12,)  0.081257
2          12-99,138-99             1776       (12, 138)  0.528414
3          12-45,138-45             1585       (12, 138)  0.471586
6                121-99             1102          (121,)  1.000000
14  123-49,121-29,22-79              626  (121, 123, 22)  0.993651
15  121-99,123-99,22-99                4  (121, 123, 22)  0.006349
8          121-99,22-99              909       (121, 22)  1.000000
5                123-99             1145          (123,)  1.000000
13             2089-281              685         (2089,)  1.000000
4                 21-99             1225           (21,)  0.532609
7                21-581             1000           (21,)  0.434783
10               21-141               75           (21,)  0.032609
1                 22-99             1792           (22,)  1.000000
9                 32-99              814           (32,)  1.000000
12               347-99              685          (347,)  1.000000
  

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

1. @JoeTha откуда ты взял 3000 ? В моем выводе это 1225/(75 1225 1000) = 0.4343

2. Куанг, пожалуйста, примите мои извинения. с моей стороны это была ошибка. но проблема по-прежнему сохраняется в отношении комбинационных кодов. Как вы видите в моем исходном фрейме данных (df). последние две строки данных. они не могут быть полностью разделены, потому что это комбинация, которая создает подкод. я имею в виду, что процентное значение должно применяться в той же логике, о которой я упоминал во второй половине моего вопроса, поскольку 123,121,22 образуют категорию подкода, на основе которой должен быть определен процент. общее количество которых в данном случае равно 630

3. @JoeTha посмотрите мой обновленный ответ, если это то, что вам нужно.

Ответ №2:

Если у вас есть несколько кодов в столбце Alpha в разном порядке, то одним из возможных решений является извлечение одного из них (например, минимального), затем возьмите часть перед ‘-‘, сохраните ее в новом столбце и используйте в дальнейшей обработке:

 df['Alpha_1'] = df.Alpha.str.split(',')
    .apply(lambda lst: min(lst)).str.split('-', expand=True)[0]
  

Результатом является:

                   Alpha  AlphaComboCount Alpha_1
0                 12-99             8039      12
1                 22-99             1792      22
2          12-99,138-99             1776      12
3          12-45,138-45             1585      12
4                 21-99             1225      21
5                123-99             1145     123
6                121-99             1102     121
7                21-581             1000      21
8          121-99,22-99              909     121
9                 32-99              814      32
10               21-141               75      21
11         12-581,12-99              711      12
12               347-99              685     347
13             2089-281              685    2089
14  123-49,121-29,22-79              626     121
15  121-99,123-99,22-99                4     121
  

Для вычисления процента от AlphaComboCount в каждой группе (с
конкретное значение Alpha_1), определите следующую функцию:

 def proc(grp):
    return (grp.AlphaComboCount / grp.AlphaComboCount.sum()
        * 100).apply('{0:.2f}%'.format)
  

Сгруппируйте df по Alpha_1 и примените эту функцию, сохранив результат
в столбце Grp_pct:

 df['Grp_pct'] = df.groupby('Alpha_1').apply(proc).reset_index(level=0, drop=True)
  

Чтобы легко проверить результат, используя строки из каждой группы вместе,
выведите df следующим образом:

 print(df.sort_values('Alpha_1'))
  

получение:

                   Alpha  AlphaComboCount Alpha_1  Grp_pct
0                 12-99             8039      12   66.38%
2          12-99,138-99             1776      12   14.66%
3          12-45,138-45             1585      12   13.09%
11         12-581,12-99              711      12    5.87%
6                121-99             1102     121   41.73%
8          121-99,22-99              909     121   34.42%
14  123-49,121-29,22-79              626     121   23.70%
15  121-99,123-99,22-99                4     121    0.15%
5                123-99             1145     123  100.00%
13             2089-281              685    2089  100.00%
4                 21-99             1225      21   53.26%
7                21-581             1000      21   43.48%
10               21-141               75      21    3.26%
1                 22-99             1792      22  100.00%
9                 32-99              814      32  100.00%
12               347-99              685     347  100.00%
  

Теперь, например, сравните раздел, касающийся Alpha_1 == 21, с
ваш ожидаемый результат для подкода 21.