2014-09-05 15 views
5

Con il seguente comando:Si possono usare i confronti per unire due frame di dati di un panda?

pandas.merge(df_1, df_2, left_on=['date'], right_on=['from_date']) 

I combinano due file da due tabelle se un valore in date -column della prima tabella è uguale al valore nel from_date -column della seconda tabella.

Ora mi piacerebbe renderlo leggermente più complesso. Ho bisogno di combinare una riga della prima tabella con una riga della seconda tabella se il valore nella colonna date della prima tabella è uguale o superiore a un valore della colonna from_date della seconda tabella e inferiore al valore nel upto_date -colonna della seconda colonna.

In SQL si potrebbe usare qualcosa di simile:

select 
    * 
from 
    table_1 
join 
    table_2 
on 
    table_1.date >= table_2.from_date 
    and 
    table_1.date < table_2.upto_date 

E 'possibile farlo in panda.

AGGIUNTO

ho trovato una soluzione, credo. Tuttavia, non sono sicuro se è elegante e ottimale:

df_1['A'] = 'A' 
df_2['A'] = 'A' 
df = pandas.merge(df_1, df_2, on=['A']) 
df = df[(df['date'] >= df['from']) & (df['date'] < df['upto'])] 
del df['A'] 
+0

Potrebbe fornire una breve campione di df1 e DF2? – FooBar

+0

Poiché i valori a cui si sta aderendo non sono più univoci, è possibile che l'unione non funzioni come previsto. Forse guarda in .join, o .concat se stai cercando di aggiungere semplicemente le due tabelle insieme – DataSwede

+0

Possibile duplicato di http://stackoverflow.com/questions/23508351/how-to-do-a-conditional-join-in -python-panda. C'è un problema relativo a Conditional Join per Pandas DataFrame (https://github.com/pydata/pandas/issues/7480) –

risposta

2

pandasql è uno strumento molto utile per l'interrogazione panda DataFrames utilizzando la sintassi di query SQLite.

Risorse

Ecco un esempio simile a quello che descrivi.

Importazioni

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
import pandas as pd 
from pandas.io.parsers import StringIO 
from pandasql import sqldf 

# helper func useful for saving keystrokes 
# when running multiple queries 
def dbGetQuery(q): 
    return sqldf(q, globals()) 

Falso alcuni dati

sample_a = """timepoint,measure 
2014-01-01 00:00:00,78 
2014-01-03 00:00:00,5 
2014-01-04 00:00:00,73 
2014-01-05 00:00:00,40 
2014-01-06 00:00:00,45 
2014-01-08 00:00:00,2 
2014-01-09 00:00:00,96 
2014-01-10 00:00:00,82 
2014-01-11 00:00:00,61 
2014-01-12 00:00:00,68 
2014-01-13 00:00:00,8 
2014-01-14 00:00:00,94 
2014-01-15 00:00:00,16 
2014-01-16 00:00:00,31 
2014-01-17 00:00:00,10 
2014-01-18 00:00:00,34 
2014-01-19 00:00:00,27 
2014-01-20 00:00:00,75 
2014-01-21 00:00:00,49 
2014-01-23 00:00:00,28 
2014-01-24 00:00:00,91 
2014-01-25 00:00:00,88 
2014-01-27 00:00:00,98 
2014-01-28 00:00:00,39 
2014-01-29 00:00:00,90 
2014-01-30 00:00:00,63 
2014-01-31 00:00:00,77 
""" 

sample_b = """from_date,to_date,measure 
2014-01-02 00:00:00,2014-01-06 00:00:00,89 
2014-01-03 00:00:00,2014-01-07 00:00:00,80 
2014-01-04 00:00:00,2014-01-05 00:00:00,44 
2014-01-05 00:00:00,2014-01-12 00:00:00,68 
2014-01-06 00:00:00,2014-01-11 00:00:00,62 
2014-01-07 00:00:00,2014-01-14 00:00:00,5 
2014-01-08 00:00:00,2014-01-09 00:00:00,23 
""" 

Leggi set di dati per creare 2 DataFrames

df1 = pd.read_csv(StringIO(sample_a), parse_dates=['timepoint']) 
df2 = pd.read_csv(StringIO(sample_b), parse_dates=['from_date', 'to_date']) 

Scrivere una query SQL

Si noti che questo utilizza l'operatore SQLite BETWEEN. Puoi anche scambiarlo e usare qualcosa come ON timepoint >= from_date AND timepoint < to_date se preferisci.

query = """ 
SELECT 
    DATE(df1.timepoint) AS timepoint 
    , DATE(df2.from_date) AS start 
    , DATE(df2.to_date) AS end 
    , df1.measure AS measure_a 
    , df2.measure AS measure_b 
FROM 
    df1 
INNER JOIN df2 
    ON df1.timepoint BETWEEN 
     df2.from_date AND df2.to_date 
ORDER BY 
    df1.timepoint; 
""" 

eseguire la query utilizzando il func aiutante

df3 = dbGetQuery(query) 

df3 
    timepoint  start   end measure_a measure_b 
0 2014-01-03 2014-01-02 2014-01-06   5   89 
1 2014-01-03 2014-01-03 2014-01-07   5   80 
2 2014-01-04 2014-01-02 2014-01-06   73   89 
3 2014-01-04 2014-01-03 2014-01-07   73   80 
4 2014-01-04 2014-01-04 2014-01-05   73   44 
5 2014-01-05 2014-01-02 2014-01-06   40   89 
6 2014-01-05 2014-01-03 2014-01-07   40   80 
7 2014-01-05 2014-01-04 2014-01-05   40   44 
8 2014-01-05 2014-01-05 2014-01-12   40   68 
9 2014-01-06 2014-01-02 2014-01-06   45   89 
10 2014-01-06 2014-01-03 2014-01-07   45   80 
11 2014-01-06 2014-01-05 2014-01-12   45   68 
12 2014-01-06 2014-01-06 2014-01-11   45   62 
13 2014-01-08 2014-01-05 2014-01-12   2   68 
14 2014-01-08 2014-01-06 2014-01-11   2   62 
15 2014-01-08 2014-01-07 2014-01-14   2   5 
16 2014-01-08 2014-01-08 2014-01-09   2   23 
17 2014-01-09 2014-01-05 2014-01-12   96   68 
18 2014-01-09 2014-01-06 2014-01-11   96   62 
19 2014-01-09 2014-01-07 2014-01-14   96   5 
20 2014-01-09 2014-01-08 2014-01-09   96   23 
21 2014-01-10 2014-01-05 2014-01-12   82   68 
22 2014-01-10 2014-01-06 2014-01-11   82   62 
23 2014-01-10 2014-01-07 2014-01-14   82   5 
24 2014-01-11 2014-01-05 2014-01-12   61   68 
25 2014-01-11 2014-01-06 2014-01-11   61   62 
26 2014-01-11 2014-01-07 2014-01-14   61   5 
27 2014-01-12 2014-01-05 2014-01-12   68   68 
28 2014-01-12 2014-01-07 2014-01-14   68   5 
29 2014-01-13 2014-01-07 2014-01-14   8   5 
30 2014-01-14 2014-01-07 2014-01-14   94   5 
+0

Python mi dice che pandasql non ha atttbute 'dbGetQuery'. Non riesco a trovare alcuna informazione online su questo modulo. Questo codice funziona davvero? –

+0

Ho definito dbGetQuery all'inizio della mia risposta. È solo una funzione di aiuto che scrivo sempre. – hernamesbarbara

+0

Oh giusto, grazie! –

Problemi correlati