我有数据框,想要更新它或根据 SQL 表中的某些输入创建新的数据框。数据框 A 有两列(ID 和 Updated_Date)。
另一方面,SQL 表还有一些列,包括 ID、Transaction_Date、Year、Month 和 Day。我的想法是将数据帧 A 的内容合并到 SQL 表中,合并后,选择 SQL 表中 Transaction_Date 之后 30 天处理的所有记录。总之,我热衷于拥有一个数据框,其中包含 df A 中的 Added_Date 之后 30 天(在 SQL 表中)发生的所有事务。SQL 表非常巨大,并且按年、月和日进行分区。我该如何优化这个流程?
我知道当数据帧转换为元组或字典时可能会发生连接,但仅此而已。示例代码如下:
import sqlite3
import pandas as pd
# create df
data = {'ID': [1, 2, 3], 'Added_Date': ['2023-02-01', '2023-04-15', '2023-03-17']}
df_A = pd.DataFrame(data)
下面是在 SQL 中在内存表中创建示例事务的代码
# Create an in-memory SQLite database
conn = sqlite3.connect(':memory:')
c = conn.cursor()
# Create the transactions table
c.execute('''CREATE TABLE transactions
(ID INTEGER, transaction_date DATE)''')
# Insert sample data into the transactions table
c.execute('''INSERT INTO transactions VALUES
(1, '2023-01-15'), (1, '2023-02-10'), (1, '2023-03-01'),
(2, '2023-04-01'), (2, '2023-04-20'), (2, '2023-05-05'),
(3, '2023-03-10'), (3, '2023-03-25'), (3, '2023-04-02')''')
预期结果应该是这样的:
ID transaction_date
1 2023-02-10
1 2023-03-01
2 2023-04-20
2 2023-05-05
3 2023-03-10
3 2023-03-25
3 2023-04-02
我希望这更清楚。
这是一种方法:
df_A['Added_Date']
将 datetime
转换为
pd.to_datetime
。df_A
作为临时表(请参阅此答案)并使用 df.to_sql
附加其数据。INNER JOIN
的查询(参见 DATE
)并使用 cursor.fetchall
。data
内的
pd.DataFrame
并添加cursor.description
中的列名称。df_A['Added_Date'] = pd.to_datetime(df_A['Added_Date'])
create_tmp = pd.io.sql.get_schema(df_A, 'temporary_table')
create_tmp = re.sub(
"^(CREATE TABLE)?",
"CREATE TEMPORARY TABLE",
create_tmp
)
c.execute(create_tmp)
df_A.to_sql('temporary_table', conn, if_exists='append', index=False)
query = """
SELECT tr.ID,
tr.transaction_date
FROM transactions AS tr
INNER JOIN temporary_table AS tmp ON tr.ID = tmp.ID
AND tr.transaction_date BETWEEN tmp.Added_Date AND DATE(tmp.Added_Date, '+30 day')"""
out = pd.DataFrame(data=c.execute(query).fetchall(),
columns=[desc[0] for desc in c.description])
输出
ID transaction_date
0 1 2023-02-10
1 1 2023-03-01
2 2 2023-04-20
3 2 2023-05-05
4 3 2023-03-25
5 3 2023-04-02
当然,也可以使用
df_A
:将结束日期添加到
pd.offsets.Day
df_A['End_Date'] = pd.to_datetime(df_A['Added_Date']) + pd.offsets.Day(30)