上下文
我有一个由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:我试图通过示例尽可能清晰,但如果不清楚,请随时提出澄清!
答案 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')