Арифметика на серии в pandas df с условной - предыдущая операция перезаписывается

Я очищаю некоторые данные о зарплате, которые мне нужно преобразовать в почасовую или годовую ставку на основе другого столбца. Я исследовал, как это сделать - что, вероятно, не самое эффективное, - но оно работает для одной строки.

Данные

import pandas as pd, numpy as np

columns = ['Location','Hourly','Annually','Monthly','Daily','Average','Hourly_Rate','Annual_Rate']
df = pd.DataFrame(columns=columns)
df.loc[1] = ['A',True,False,False,False,10.10,np.nan,np.nan]
df.loc[2] = ['B',False,True,False,False,50000,np.nan,np.nan]

df['Annual_Rate'] = (df['Average'] * 2080).where(df['Hourly'] == True) #need this line to run and not get overwritten
df['Annual_Rate'] = df['Average'].where(df['Annually'] == True ) #overwrites prior line
df['Annual_Rate'] = df['Average'].where(df['Annually'] == True & pd.isna(df['Annual_Rate'])) #overwrites prior line and is incorrect

df['Hourly_Rate'] = (df['Average'] / 2080).where([(df['Annually'] == True) & (pd.isnull(df['Hourly_Rate']))])
df['Hourly_Rate'] = df['Average'].where(df['Hourly'] == True & (pd.isna(df['Hourly_Rate'])))
df['Hourly_Rate'] = df['Average'].where(df['Hourly'] == True)
df.head(10)

Вот строки, которые должны быть / мне нужны для работы:

df['Hourly_Rate'] = (df['Average'] / 2080).where([(df['Annually'] == True) & (pd.isnull(df['Hourly_Rate']))])
df['Annual_Rate'] = (df['Average'] * 2080).where(df['Hourly'] == True)

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

+---+----------+--------+----------+---------+-------+---------+-------------+-------------+
|   | Location | Hourly | Annually | Monthly | Daily | Average | Hourly_Rate | Annual_Rate |
+---+----------+--------+----------+---------+-------+---------+-------------+-------------+
| 1 | A        | TRUE   | FALSE    | FALSE   | FALSE |    10.1 |        10.1 |       21008 |
| 2 | B        | FALSE  | TRUE     | FALSE   | FALSE |   50000 | 24.03846154 |       50000 |
+---+----------+--------+----------+---------+-------+---------+-------------+-------------+

Заранее спасибо.

Можете ли вы показать нам, чего вы ожидаете от желаемого результата?

jpp 10.08.2018 15:43

Да - извините за это - добавил два столбца / значения, которые я ищу.

Hatt 10.08.2018 15:48
2
2
77
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

pd.Series.where не работает так же, как numpy.where. Последнее можно использовать для указания векторизованного условия if-else и, вероятно, вам понадобится:

df['Annual_Rate'] = np.where(df['Hourly'], df['Average'] * 2080, df['Average'])

df['Hourly_Rate'] = np.where(df['Annually'] & df['Hourly_Rate'].isnull(),
                             df['Average'] / 2080, df['Average'])

pd.Series.where обновляет серию с заданным значением, где выполняется условие нет, в противном случае остается неизменным (в данном случае NaN, если не указано), как отмечено в документы:

Return an object of same shape as self and whose corresponding entries are from self where cond is True and otherwise are from other.

Также обратите внимание, что вы можете использовать логические серии напрямую, а не тестировать df[col] == True.

Хорошо, большое спасибо - я просто реализую это сейчас, чтобы проверить - и спасибо за другое направление, проверяя, почему это не работает в моем скрипте - а также спасибо за логическое примечание.

Hatt 10.08.2018 16:00

Другие вопросы по теме