Объединение нескольких DataFrame

Не получается объединить датафреймы представленные ниже. Изначальный датафрейм df спарсил из xml. Остальные находятся в таблицах Excel. Нужно объединить их с условиями, что определенный номер счета означает определенные виды расходов и доходов, а отдел соответствует департаменту. При этом доход должен быть положительным числом, а расход отрицательным. DataFrame df_finally это нужный конечный результат. Спасибо всем за ответы заранее )

import pandas as pd
        
df = pd.DataFrame([['123', 'ФАКТ', '2022','Январь', 100, 'Бухгалтерия', 'Выплата зарплаты'],
                   ['456', 'ФАКТ', '2022','Январь', 200, 'Склад', 'Списание'],
                   ['789', 'ФАКТ', '2022','Январь', 300, 'Отдел продаж', 'Продажи']],
                   columns=['Счет', 'Вид', 'Год', 'Месяц', 'Сумма', 'Отдел', 'Статья'])
df_info = pd.DataFrame([['123', 'Расходы', 'Основные расходы'],
                        ['789', 'Доходы', 'Доход от продажи'],
                        ['111', 'Расходы', 'Операц расходы'],
                        ['456', 'Расходы', 'Списания и возвраты']],
                        columns=['Счет', 'Статья_01', 'Статья_02'])
        
df_info_departments = pd.DataFrame([['Бухгалтерия', 'Финансовый'],
                                  ['Отдел продаж', 'Коммерческий'],
                                  ['Склад', 'Логистики']],
                                  columns=['Отдел', 'Департамент'])
        
df_info_st = pd.DataFrame([['Выплата зарплаты', 'ФОНД ЗП'],
                           ['Списание', 'Расходы'],
                           ['Продажи', 'Доходы']],
                           columns=['Статья', 'Статья_03'])
df_finally = pd.DataFrame([['123', 'ФАКТ', '2022','Январь', 'Расходы', 'Основные расходы', 'ФОНД ЗП',100,
                            'Бухгалтерия', 'Выплата зарплаты', 'Финансовый'],
                           ['456', 'ФАКТ', '2022','Январь', 'Расходы', 'Списания и возвраты', 'Расходы',200,
                            'Склад', 'Списание', 'Логистики'],
                           ['789', 'ФАКТ', '2022','Январь', 'Доходы', 'Доход от продажи', 'Доходы', 300,
                            'Отдел продаж', 'Продажи', 'Коммерческий']],
                          columns=['Счет', 'Вид', 'Год', 'Месяц', 'Статья_01', 'Статья_02', 'Статья_03', 'Сумма',
                                   'Отдел', 'Статья', 'Департамент'])
print(df, '\n', df_info, '\n', df_info_departments, '\n', df_info_st, '\n', df_finally)

Ответы (2 шт):

Автор решения: web developer

Ниже приведен самый чистый и понятный способ объединения нескольких фреймов данных, если не используются сложные запросы.

Просто объедините с DATE в качестве индекса и объедините, используя метод OUTER (чтобы получить все данные).

  import pandas as pd
from functools import reduce

df1 = pd.read_table('file1.csv', sep=',')
df2 = pd.read_table('file2.csv', sep=',')
df3 = pd.read_table('file3.csv', sep=',')

Теперь в основном загрузите все файлы, которые у вас есть в качестве фрейма данных, в список. А затем объедините файлы с помощью mergeили reducefunction.

# compile the list of dataframes you want to merge
data_frames = [df1, df2, df3]

Примечание: вы можете добавить любое количество фреймов данных в приведенный выше список. Это хорошая часть этого метода. Никаких сложных запросов.

Чтобы сохранить значения, относящиеся к одной и той же дате, вам необходимо объединить их на DATE

df_merged = reduce(lambda  left,right: pd.merge(left,right,on=['DATE'],
                                            how='outer'), data_frames)

# if you want to fill the values that don't exist in the lines of merged dataframe simply fill with required strings as

df_merged = reduce(lambda  left,right: pd.merge(left,right,on=['DATE'],
                                            how='outer'), data_frames).fillna('void')
Теперь на выходе будут значения с той же даты в тех же строках.

Вы можете заполнить несуществующие данные из разных фреймов для разных столбцов, используя fillna(). Затем при желании запишите объединенные данные в CSV-файл.

pd.DataFrame.to_csv(df_merged, 'merged.txt', sep=',', na_rep='.', index=False)
→ Ссылка
Автор решения: strawdog

С порядком колонок уж сами как-то разбирайтесь:

rres = df.merge(df_info, on="Счет").merge(
    df_info_departments, on="Отдел").merge(
    df_info_st, on="Статья")

res:

  Счет   Вид   Год   Месяц  Сумма         Отдел            Статья Статья_01            Статья_02   Департамент Статья_03
0  123  ФАКТ  2022  Январь    100   Бухгалтерия  Выплата зарплаты   Расходы     Основные расходы    Финансовый   ФОНД ЗП
1  456  ФАКТ  2022  Январь    200         Склад          Списание   Расходы  Списания и возвраты     Логистики   Расходы
2  789  ФАКТ  2022  Январь    300  Отдел продаж           Продажи    Доходы     Доход от продажи  Коммерческий    Доходы
→ Ссылка