使用条件合并2个相似的数据帧

时间:2019-10-02 14:01:40

标签: python pandas dataframe merge


上下文
我有一个由csv文件组成的数据库。我每个月都会收到新文件,并且需要使用这些文件更新数据库。但是,我无法覆盖对一个重要数据的更改,因为我需要跟踪它的历史记录。

问题
我有2个看起来像这样的数据帧-前3列是关键:

Database dataframe (DD)
ID1  ID2  ID3  important_data  some_date1  some_data2  date
1    2    3    10              X            Y          2019-09-19 14:53:16.107278
4    5    6    10              M            N          2019-07-15 14:53:16.107278

Database client (DC)
ID1  ID2  ID3  important_data  some_date1  some_data2  date
1    2    3    15              A            B          2019-10-19 14:53:16.107278
4    5    6    10              O            P          2019-09-18 14:53:16.107278

第一个DF是我数据库中的那个DF。第二个是我的客户给的新的。
如果与日期中最后一个匹配的元组相比,“ important_data”没有更改(ID为4 5 6的情况),我将使用新的元数据覆盖旧数据:

New Database dataframe (DD)
ID1  ID2  ID3  important_data  some_date1  some_data2  date
1    2    3    10              X            Y          2019-09-19 14:53:16.107278
4    5    6    10              O            P          2019-09-18 14:53:16.107278

其他(ID 1 2 3-或如果原始数据是全新的),我需要在数据库框架中编写一个全新的原始数据:

New Database dataframe (DD)
ID1  ID2  ID3  important_data  some_date1  some_data2  date
1    2    3    10              X            Y          2019-09-19 14:53:16.107278
1    2    3    15              A            B          2019-10-19 14:53:16.107278
4    5    6    10              M            N          2019-07-15 14:53:16.107278

问题
我可以使用这样的常规嵌套ifs(算法)来做到这一点:

Select last_in_date rows in DD (for each IDs) in new dataframe DD_pending // we only need the last entries
For rowC in DC
new = true
 For rowD in DD_pending
  If matching IDs then
   new = false
   If same "important_data" then overwrite_everything
   Else create_new_row in DD
if new then create_new_row in DD
Merge DD_pending with DD, drop duplicates

但是,根据机器所需的资源,可以使用熊猫合并来简化它吗?我尝试查看this,但并不完全相同。我也在看concat,但找不到解决方法。

谢谢!

Ps:我试图通过示例尽可能清晰,但如果不清楚,请随时提出澄清!

1 个答案:

答案 0 :(得分:0)

这应该做到。

# imports
import pandas as pd
import datetime

# ignore (just for setting up the problem)
db_df = pd.DataFrame({
    "ID1": [1, 4],
    "ID2": [2, 5],
    "ID3": [3, 6],
    "important_data": [10, 10],
    "some_date1": ["X", "M"],
    "some_date2": ["Y", "N"],
    "date": [datetime.datetime.strptime("2019-09-19 14:53:16.107278", '%Y-%m-%d %H:%M:%S.%f'),
             datetime.datetime.strptime("2019-09-19 14:53:16.107278", '%Y-%m-%d %H:%M:%S.%f')]
})

# ignore (just for setting up the problem)
db_df_client = pd.DataFrame({
    "ID1": [1, 4],
    "ID2": [2, 5],
    "ID3": [3, 6],
    "important_data": [15, 10],
    "some_date1": ["A", "O"],
    "some_date2": ["B", "P"],
    "date": [datetime.datetime.strptime("2019-09-19 14:53:16.107278", '%Y-%m-%d %H:%M:%S.%f'),
             datetime.datetime.strptime("2019-09-19 14:53:16.107278", '%Y-%m-%d %H:%M:%S.%f')]
})

# the line you care about
pd.concat([db_df, db_df_client]).drop_duplicates(subset=['ID1','ID2','ID3','important_data'], keep='first')