一尘不染

合并其中一个值介于其他两个值之间pandas数据框

python

我需要在一个标识符和一个数据帧中的日期位于另一个数据帧中的两个日期之间的条件下合并两个熊猫数据帧。

数据框A具有日期(“ fdate”)和ID(“ cusip”):

在此处输入图片说明

我需要将此与此数据框B合并:

在此处输入图片说明

A.cusip==B.ncusipA.fdate之间B.namedtB.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'])]

这真的是最好的方法吗?似乎最好是在合并中进行过滤,以免在合并后但在过滤器完成之前有一个非常大的数据帧。


阅读 208

收藏
2021-01-20

共1个答案

一尘不染

如您所说,这在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
2021-01-20