我需要在一个标识符和一个数据帧中的日期位于另一个数据帧中的两个日期之间的条件下合并两个熊猫数据帧。
数据框A具有日期(“ fdate”)和ID(“ cusip”):
我需要将此与此数据框B合并:
在A.cusip==B.ncusip和A.fdate之间B.namedt和B.nameenddt。
A.cusip==B.ncusip
A.fdate
B.namedt
B.nameenddt
在SQL中,这是微不足道的,但是我看到的如何在pandas中做到这一点的唯一方法是,首先在标识符上无条件合并,然后在日期条件上进行过滤:
df = pd.merge(A, B, how='inner', left_on='cusip', right_on='ncusip') df = df[(df['fdate']>=df['namedt']) & (df['fdate']<=df['nameenddt'])]
这真的是最好的方法吗?似乎最好是在合并中进行过滤,以免在合并后但在过滤器完成之前有一个非常大的数据帧。
如您所说,这在SQL中非常容易,那么为什么不在SQL中这样做呢?
import pandas as pd import sqlite3 #We'll use firelynx's tables: presidents = pd.DataFrame({"name": ["Bush", "Obama", "Trump"], "president_id":[43, 44, 45]}) terms = pd.DataFrame({'start_date': pd.date_range('2001-01-20', periods=5, freq='48M'), 'end_date': pd.date_range('2005-01-21', periods=5, freq='48M'), 'president_id': [43, 43, 44, 44, 45]}) war_declarations = pd.DataFrame({"date": [datetime(2001, 9, 14), datetime(2003, 3, 3)], "name": ["War in Afghanistan", "Iraq War"]}) #Make the db in memory conn = sqlite3.connect(':memory:') #write the tables terms.to_sql('terms', conn, index=False) presidents.to_sql('presidents', conn, index=False) war_declarations.to_sql('wars', conn, index=False) qry = ''' select start_date PresTermStart, end_date PresTermEnd, wars.date WarStart, presidents.name Pres from terms join wars on date between start_date and end_date join presidents on terms.president_id = presidents.president_id ''' df = pd.read_sql_query(qry, conn)
df:
PresTermStart PresTermEnd WarStart Pres 0 2001-01-31 00:00:00 2005-01-31 00:00:00 2001-09-14 00:00:00 Bush 1 2001-01-31 00:00:00 2005-01-31 00:00:00 2003-03-03 00:00:00 Bush