Сравнение значений в нескольких столбцах и возврат всех уменьшающихся областей

#python #pandas #numpy

Вопрос:

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

Компания 2021 Регион 1 Продажи 2021 Регион 2 Продажи 2020 Регион 1 Продажи 2020 Регион 2 Продажи
Компания 1 300000 150000 250000 149000
Компания 2 10000 17000 100000 80000
Компания 3 12000 20000 22000 90000

Я хотел бы сравнить каждый регион за каждый год, чтобы определить, какие регионы сократились в 2021 году. Одно предостережение состоит в том, что для подсчета региональных продаж необходимо, чтобы они составляли не менее 25 000 долларов. Поэтому я хочу добавить новую колонку со всеми названиями регионов, продажи которых в 2021 году составили менее 25 000 долларов, но более 25 000 долларов в 2020 году. Результат будет выглядеть так, хотя для сравнения будет больше столбцов или «областей», чем 2.

Компания 2021 Регион 1 Продажи 2021 Регион 2 Продажи 2020 Регион 1 Продажи 2020 Регион 2 Продажи 2021 Потерянные регионы
Компания 1 300000 150000 250000 149000 Нет
Компания 2 10000 17000 100000 80000 Регион 1; Регион 2
Компания 3 12000 20000 22000 90000 Регион 2

Заранее благодарю вас за любую помощь, и не спешите с этим. Надеюсь, есть краткий способ сделать это без использования «если-то» и написания множества комбинаций.

Ответ №1:

 number_of_regions = 2 # You have to change this
def find_declined_regions(row):
    result = []
    for i in range(1, number_of_regions 1):
        if row[f"2021 Region {i} Sales"] < 25000 and row[f"2020 Region {i} Sales"] > 25000:
           result.append(f"Region {i}")
    return "; ".join(result)

df.apply(find_declined_regions, axis=1)    
 

df это ваш фрейм данных, и вы должны изменить number_of_regions его в зависимости от вашей проблемы.

ИЗМЕНИТЬ: если все имена столбцов разные, есть два случая:

1 — У вас есть список всех регионов, поэтому вы можете сделать это:

 for region in all_regions:
        if row[f"2021 {region} Sales"] < 25000 and row[f"2020 {region} Sales"] > 25000:
 

2 — У вас нет списка всех регионов, поэтому вам нужно его создать:

 all_regions = [col[5:-6] for col in df.columns[1:int(len(df.columns)/2) 1]]
 

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

1. Большое вам за это спасибо. Один вопрос в учебных целях, когда у вас будет такая возможность… как бы работал этот цикл, если бы все имена столбцов были разными? Например, вместо региона 1, региона 2 и т. Д., Если бы у меня были продажи на северо-западе, продажи на юго-востоке и т. Д.

2. Отредактировал ответ @nb1214

3. Большое вам спасибо, я все еще в замешательстве, когда дело доходит до объединения исходного ответа и редактирования, но у меня есть то, что мне нужно, чтобы понять это сейчас.