У меня есть два фрейма данных, dfA
и dfB
, разной формы и с разным порядком. dfA
содержится в dfB
.
В этом примере есть 3 столбца: «Название должности», «Отдел работы» и «Заработная плата». У dfA
отсутствуют значения в столбце «Заработная плата», поэтому я хотел бы получить эти значения от dfB
.
Если «Название должности» и «Отдел работы» совпадают между dfA
и dfB
, «Зарплата за работу» тоже такая же, поэтому я могу использовать «Зарплату за работу» из dbB
для заполнения dfA
.
Например, каждый «Учитель английского языка» в отделе «Учителя» имеет зарплату X, а «Учитель английского языка» в отделе «Частные преподаватели» имеет другую зарплату, хотя должность та же.
Однако мне пока не удалось найти код для этого.
Мой мыслительный процесс был таким, хотя я думаю, что он совершенно неверен:
condition_A = (dfA['Job Title'] == dfB['Job Title'])
condition_B = (dfA['Job Department'] == dfB['Job Department'])
dfA.loc[(condition_A) & (condition_B), 'Job Salary'] = dfB.loc[(condition_A) & (condition_B), 'Job Salary']
Эта попытка явно не сработала.
dataA = {
'Job Title': ['ET', 'FT', 'ET', 'ST', 'ST'],
'Job Department': ['T', 'T', 'PT', 'T', 'PT'],
'Job Salary': [np.nan, 1500, 1000, np.nan, np.nan]
}
dfA = pd.DataFrame(dataA)
dataB = {
'Job Title': ['ST', 'ET', 'RT', 'FT', 'ST', 'PT', 'ET'],
'Job Department': ['T', 'T', 'PT', 'T', 'PT', 'T', 'PT'],
'Job Salary': [2000, 800, 1700, 1500, 2500, 700, 1000]
}
dfB = pd.DataFrame(dataB)
Желаемый результат (пропущенные значения dfA
заполнены из dfB
):
dataA = {
'Job Title': ['ET', 'FT', 'ET', 'ST', 'ST'],
'Job Department': ['T', 'T', 'PT', 'T', 'PT'],
'Job Salary': [800, 1500, 1000, 2000, 2500]
}
dfA = pd.DataFrame(dataA)
Заранее спасибо!
Попробую сделать это сейчас, дай мне минутку. Я отредактирую пост.
Все еще не воспроизводимо... Используйте dict и предоставьте больше данных. Копирование, которое испортит данные md, займет вечность.
Наконец мне удалось продемонстрировать это с помощью словаря. Пожалуйста, дайте мне знать, если необходимы дополнительные данные или информация.
dfA = pd.merge(
dfA,
dfB,
how = "left",
on=["Job Title", "Job Department"],
suffixes=("_dropme", ""),
).drop(columns='Job Salary_dropme')
Результаты в таблице, как вы описываете, за исключением последнего значения зарплаты на работе, которое я предполагаю, если с вашей стороны допущена ошибка, поскольку в приведенных примерах для dfA
и dfB
не существует названия-отдела-зарплаты.
Я думаю, это может сработать. Не могли бы вы объяснить, что делают how
и suffixes
?
Без проблем. Опция pd.merge
с опцией how='left'
по сути выполняет левое соединение sql (где находится левая таблица dfA
). Это сохраняет dfA
затемнение. При выполнении SQL-подобных соединений необходим уникальный ключ. В данном случае это кортеж Должность-Отдел работы. Остальные столбцы добавляются как часть объединения. В основном эти две таблицы имеют общий столбец «Зарплата за работу» — как мы можем представить их в одной таблице, если у них одинаковое имя? Чтобы решить эту проблему, в столбец suffixes=("_dropme", "")
добавляются суффиксы к «Зарплата за работу», чтобы имена столбцов были уникальными. Надеюсь, это поможет!
Тысму за помощь и разъяснения. Ваше решение сработало. Я не могу проголосовать против, потому что у меня недостаточно репутации, но я проверил ваше предложение как решение.
Вы можете заранее удалить столбец из dfA
: dfA.drop('Job Salary', axis=1).merge(dfB, on=['Job Title', 'Job Department'], how='left')
. Или: dfA[['Job Title', 'Job Department']].merge(dfB, on=['Job Title', 'Job Department'], how='left')
. Вам не нужно будет устанавливать suffixes
таким образом.
@ouroboros1 Отличный трюк! Однако с помощью этого решения мы бы предположили, что какие бы dfA
ни были зарплаты, они есть и у dfB
- что, я полагаю, работает в этом конкретном (небольшом) примере. Крайний случай, о котором я здесь напрасно думаю, — это когда зарплата в dfA
отличается от dfB
, но ни одна из них не равна нулю — какой из них мы бы приняли за истину.
ОП прямо говорит, что dfA
и dfB
будут иметь одинаковую зарплату для значений, отличных от NaN. В противном случае, конечно, можно было бы использовать оба столбца рядом.
@ouroboros1 ну, я с уважением не согласен - ОП мог бы неявно сказать, что зарплаты dfA
и dfB
одинаковы, когда он упомянул, что dfA
содержится в dfB
. Содержащийся в этом контексте может означать несколько вещей, одна из которых содержится в столбцах, но не в значениях.
ОП пишет: Если «Название должности» и «Отдел трудоустройства» совпадают между dfA и dfB, «Зарплата за работу» тоже такая же, поэтому я могу использовать «Зарплату за работу» из dbB для заполнения dfA. Я не вижу ничего двусмысленного в этом утверждении.
Двусмысленность для меня возникает в контексте, ведущем к этому предложению, когда ОП упоминает, что у dfA отсутствуют значения в столбце «Зарплата за работу», поэтому я хотел бы получить эти значения от dfB, что означает, что следующее совпадение, о котором говорит ОП , то есть ваша цитата, относится только к случаям, когда в dfA отсутствуют зарплаты, что приводит к двусмысленности в случаях, когда есть совпадение по ключу, но у dfs разные зарплаты.
Для комбинации «Название должности» и «Отдел должностей» может быть только одна «Зарплата за работу», и оба dfA
и dfB
имели бы одинаковые значения, если бы в A не было значений NaN. Когда я сказал, что dfA
содержится в dfB
, я имел в виду, что могу найти каждую запись A в B, но в моем случае реальные фреймы данных не так просты, столбцов намного больше, и для завершения мне действительно нужна была только информация «Зарплата за работу» из B. А.
покажи нам, а не рассказывай нам. Можете ли вы предоставить воспроизводимый пример: stackoverflow.com/help/minimal-reproducible-example