Добавление символа в столбец на основе порядка возрастания другого столбца, если условие выполнено pandas

#python #pandas #dataframe

#python #pandas #фрейм данных

Вопрос:

Застрял на проблеме с данными в pandas. Смотрите данные ниже:

 | Product | Level | Cost |
 --------- ------- ------
| Prod_A  | L1    | 100  |
| Prod_A  | L1    | 100  |
| Prod_A  | L1    | 200  |
| Prod_A  | L2    | 100  |
| Prod_A  | L3    | 100  |
| Prod_B  | L1    | 150  |
| Prod_B  | L1    | 150  |
| Prod_B  | L2    | 200  |
| Prod_B  | L2    | 300  |
| Prod_C  | L3    | 100  |
  

Правила следующие:

  1. Только одна стоимость для каждой уникальной комбинации (продукта, уровня).
  2. Если для каждой уникальной комбинации (продукта, уровня) несколько значений стоимости, Добавьте букву к значению уровня (L1 A, L1 B и т. Д.) На основе значения затрат (L1 A — наименьшая стоимость).
  3. Если комбинация (продукт, уровень) имеет уникальную стоимость, тогда ничего не делайте.

Желаемый результат:

 | Product | Level | Cost |
 --------- ------- ------
| Prod_A  | L1 A  | 100  |
| Prod_A  | L1 A  | 100  |
| Prod_A  | L1 B  | 200  |
| Prod_A  | L2    | 100  |
| Prod_A  | L3    | 100  |
| Prod_B  | L1    | 150  |
| Prod_B  | L1    | 150  |
| Prod_B  | L2 A  | 200  |
| Prod_B  | L2 B  | 300  |
| Prod_C  | L3    | 100  |
  

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

1. должен ли желаемый результат Level for Prod_A быть L1 A , L1 B когда стоимость равна 100 . Prod_A 200 Я думаю, что стоимость и стоимость Level должны оставаться такими, как L1 указано в вашей заметке. Я правильно понял? Аналогично, для Prod_B , у нас есть два L1 для стоимости 150 so , не должно ли это также заканчиваться A and B ?

2. @JoeFerndz итак, поскольку Prod_B L1 имеет только одну стоимость 150 , мы можем игнорировать. Но поскольку Prod_B и L2 и 2 разные стоимости ( 200 , 300 ), нам нужно добавить букву в L2 . Это помогает?

Ответ №1:

Вот один из способов:

 charlist='ABCDEFG'
dd = {k:' ' v for k, v in enumerate(charlist)}
df['Level']  = df.groupby(['Product', 'Level'])['Cost']
                 .transform(lambda x: x.factorize()[0] if x.nunique()>1 else -1)
                 .map(dd).fillna('')
  

Вывод:

   Product Level  Cost
0  Prod_A  L1 A   100
1  Prod_A  L1 A   100
2  Prod_A  L1 B   200
3  Prod_A    L2   100
4  Prod_A    L3   100
5  Prod_B    L1   150
6  Prod_B    L1   150
7  Prod_B  L2 A   200
8  Prod_B  L2 B   300
9  Prod_C    L3   100
  

Подробные сведения:

Сначала создайте словарь символов для добавления.

Затем groupby продукт и уровень, используя transform уникальное «кодирование» каждой стоимости, pd.Series.factorize если есть только одна сумма затрат, затем используйте -1.

Наконец, сопоставьте результаты «закодированной» стоимости с использованием словаря и заполните пустую строку.