1. ホーム
  2. python

[解決済み] ある値が他の2つの値の間にある場合、pandasのデータフレームをマージする [重複] 。

2023-05-30 03:12:05

質問

識別子と、一方のデータフレームの日付が他方のデータフレームの2つの日付の間にあるという条件で、2つのpandasデータフレームをマージする必要があります。

データフレーム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'])]

これは本当に最良の方法なのでしょうか?マージ後にフィルターが完了する前に、潜在的に非常に大きなデータフレームを持つことを避けるために、マージ内でフィルターすることができれば、はるかに良いように思われます。

どのように解決するのですか?

おっしゃるとおり、これは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