#python #pandas
#питон #панды
Вопрос:
Вот мои данные —
ID,Pay1,Pay2,Pay3,Low,High,expected_output
1,12,21,23,1,2,21
2,21,34,54,1,3,54
3,74,56,76,1,1,74
Цель состоит в том, чтобы вычислить максимальное Pay
значение каждой строки в соответствии Pay
с индексом столбца, указанным в Low
и High
столбцы.
Например, для строки 1 вычислите max
of Pay1
и Pay2
столбцы как Low
и High
равны 1 и 2.
Я попытался создать динамическую строку, а затем использовать eval
функцию, которая работает плохо.
Ответ №1:
Идея заключается в том, чтобы фильтровать только Pay
столбцы, а затем с помощью numpy broadcasting выбирать столбцы по Low
и High
столбцам, передавать DataFrame.where
и получать в последний раз max
:
df1 = df.filter(like='Pay')
m1 = np.arange(len(df1.columns)) >= df['Low'].to_numpy()[:, None] - 1
m2 = np.arange(len(df1.columns)) <= df['High'].to_numpy()[:, None] - 1
df['expected_output'] = df1.where(m1 amp; m2, 0).max(axis=1)
print (df)
ID Pay1 Pay2 Pay3 Low High expected_output
0 1 12 21 23 1 2 21
1 2 21 34 54 1 3 54
2 3 74 56 76 1 1 74
Комментарии:
1. Спасибо @jezrael! Сократил время выполнения с 13 секунд до 64 мс на выборке из 12 тыс. строк!
Ответ №2:
Альтернатива; Я ожидаю, что решение @jezrael будет быстрее, поскольку оно находится в numpy и pd.wide_to_long
не особенно быстрое:
grouping = (
pd.wide_to_long(df.filter(regex="^Pay|Low|High"),
i=["Low", "High"],
stubnames="Pay",
j="num")
.query("Low==num or High==num")
.groupby(level=["Low", "High"])
.Pay.max()
)
grouping
Low High
1 1 74
2 21
3 54
Name: Pay, dtype: int64
df.join(grouping.rename("expected_output"), on=["Low", "High"])
ID Pay1 Pay2 Pay3 Low High expected_output
0 1 12 21 23 1 2 21
1 2 21 34 54 1 3 54
2 3 74 56 76 1 1 74