У меня есть фрейм данных с четырьмя столбцами со значениями от 0 до 100. В новом столбце я хочу присвоить значение, зависящее от значений в первых четырех столбцах.

Значениям из первых четырех столбцов будет присвоен номер 0, 1 или 2, а затем они будут суммированы следующим образом:

0–30 = 0

31-70 = 1

71 - 100 = 2

Таким образом, максимальное число в пятом столбце будет 8, а минимальное - 0.

В примере фрейма данных ниже пятого столбца должно получиться 2, 3. (На всякий случай, я не описал это четко).

Я все еще новичок в python, и на данном этапе единственная строка, которая у меня в луке, - это очень длинный и громоздкий многократно вложенный оператор if, за которым следует df['E'] = df.apply().

Мой вопрос в том, какая функция / метод является наилучшей и наиболее эффективной для заполнения пятого столбца.

data = {
        'A':  [50, 90],
        'B': [2, 4],
        'C': [20, 80],
        'D': [75, 72],
        }

df = pd.DataFrame(data)
2
grdnryn 24 Ноя 2021 в 00:43
Проверить, находится ли значение от 0 до 30, бесполезно, потому что возвращаемое значение равно 0.
 – 
Corralien
24 Ноя 2021 в 01:05

1 ответ

Лучший ответ

Изменить

Более полный метод с np.select:

condlist = [(0 <= df) & (df <= 30),
            (31 <= df) & (df <= 70),
            (71 <= df) & (df <= 100)]
choicelist = [0, 1, 2]

df['E'] = np.select(condlist, choicelist).sum(axis=1)
print(df)

# Output
    A  B   C   D  E
0  50  2  20  75  3
1  90  4  80  72  6

Используйте pd.cut после сглаживания ваш фрейм данных в один столбец с melt :

df['E'] = pd.cut(pd.melt(df, ignore_index=False)['value'],
                 bins=[0, 30, 70, 100], labels=[0, 1, 2]) \
            .cat.codes.groupby(level=0).sum()
print(df)

# Output:
    A  B   C   D  E
0  50  2  20  75  3
1  90  4  80  72  6

Детали:

>>> pd.melt(df, ignore_index=False)
  variable  value
0        A     50
1        A     90
0        B      2
1        B      4
0        C     20
1        C     80
0        D     75
1        D     72

>>> pd.cut(pd.melt(df, ignore_index=False)['value'],
                 bins=[0, 30, 70, 100], labels=[0, 1, 2])
0    1
1    2
0    0
1    0
0    0
1    2
0    2
1    2
Name: value, dtype: category
Categories (3, int64): [0 < 1 < 2]
1
Corralien 24 Ноя 2021 в 01:04
Легкий! Спасибо. Вы смогли сделать это за меня, хотя в моем примере я допустил ошибку в расчетах!
 – 
grdnryn
24 Ноя 2021 в 11:28