2014-09-05 25 views
5

Với lệnh sau:Có thể sử dụng so sánh để hợp nhất hai khung dữ liệu gấu trúc không?

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

tôi kết hợp hai dòng từ hai bảng nếu một giá trị trong date -column của bảng đầu tiên là bằng với giá trị trong from_date -column của bảng thứ hai.

Bây giờ tôi muốn làm cho nó phức tạp hơn một chút. Tôi cần phải kết hợp một hàng từ bảng đầu tiên với một hàng từ bảng thứ hai nếu giá trị trong cột date của bảng đầu tiên bằng hoặc lớn hơn giá trị của from_date-cột của bảng thứ hai và nhỏ hơn giá trị trong upto_date-cột của cột thứ hai.

Trong SQL ai sử dụng một cái gì đó như thế:

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

Có thể làm điều đó trong gấu trúc.

THÊM

Tôi tìm thấy một giải pháp, tôi nghĩ. Tuy nhiên, tôi không chắc chắn nếu nó là thanh lịch và tối ưu:

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

Ông có thể cung cấp một mẫu ngắn df1 và df2 của bạn? – FooBar

+0

Vì các giá trị bạn đang tham gia không còn là duy nhất, bạn có thể không hợp nhất hoạt động như mong đợi. Có lẽ nhìn vào .join, hoặc .concat nếu bạn đang tìm cách chỉ cần thêm hai bảng cùng nhau – DataSwede

+0

Có thể trùng lặp của http://stackoverflow.com/questions/23508351/how-to-do-a-conditional-join-in -python-pandas. Có một vấn đề được đề xuất liên quan đến Điều kiện Tham gia cho Pandas DataFrame (https://github.com/pydata/pandas/issues/7480) –

Trả lời

2

pandasql là một công cụ khá hữu ích cho các truy vấn gấu trúc DataFrames sử dụng cú pháp truy vấn SQLite.

Tài

Đây là một ví dụ tương tự như ví dụ bạn mô tả.

Imports

#!/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()) 

Fake một số dữ liệu

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 
""" 

bộ dữ liệu đọc để tạo ra 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']) 

Viết truy vấn SQL

Lưu ý rằng điều này sử dụng toán tử SQLite BETWEEN. Bạn cũng có thể hoán đổi nó ra và sử dụng một cái gì đó như ON timepoint >= from_date AND timepoint < to_date nếu bạn thích.

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; 
""" 

Chạy truy vấn bằng cách sử dụng Func helper

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 cho tôi biết pandasql không có 'dbGetQuery' attirbute. Tôi cũng không thể tìm thấy bất kỳ thông tin trực tuyến nào trên mô-đun này. Mã này có thực sự hoạt động không? –

+0

Tôi đã xác định dbGetQuery ở đầu câu trả lời của mình. Nó chỉ là một hàm trợ giúp mà tôi luôn viết. – hernamesbarbara

+0

Ồ đúng rồi, cảm ơn! –

Các vấn đề liên quan