簡體   English   中英

我怎樣才能像子查詢一樣在 python 中進行條件連接?

[英]How can I do conditional joins in python like subquery?

我有 2 個 df。

我想獲取 df2 的類別,但沒有公共鍵。

df1 的代碼應該在 range1 和 range2 之間。

df2 的 s_date 只有 2 個值(20210101、20220101)

df1

代碼 日期
A51 20221215
C52 20221215
A51 20211215
D89 20211215

df2

范圍 1 范圍2 s_date 類別
A00 B99 20220101 一種
C50 C60 20220101
A00 B60 20210101 AA
D00 D90 20210101 DD

對於輸出,我使用如下語句的 SQL 完成了這項工作,

但我想用 python(pandas) 來完成這項工作。

輸出

代碼 日期 類別
A51 20221215 一種
C52 20221215
A51 20211215 AA
D89 20211215 DD
SELECT 
 code, date,
 CASE WHEN date >= '20220101'
 THEN (SELECT category
      FROM df2
      WHERE code BETWEEN range1 AND range2
      AND   s_date = '20220101'
 ELSE (SELECT category
      FROM df2
      WHERE code BETWEEN range1 AND range2
      AND   s_date = '20210101') END AS category
FROM df1

謝謝。

您可以直接在 python 中比較字符串。 例如,'A50' > 'A00' 將返回True ,而 'A50' > 'B00' 將返回False 我們可以使用它按此值過濾 df2。

這是它可能在代碼中看到的奶牛:

categories = []
for row in df1.values:
    code = row['code']
    date = row['date']
    if date >= '20220101':
        category = df2[(df2['range1'] < code) & (code < df2['range2']) & (df2['s_date'] == '20220101')]['category']
    else:
        category = df2[(df2['range1'] < code) & (code < df2['range2']) & (df2['s_date'] == '20210101')]['category']
    categories.append(category)
df1['category'] = categories

也許有更優雅的方法,但主要模式就是這樣。

datecode對行進行排序。 一種方法是定義這些列的整數編碼,然后使用merge_asof組合數據幀。

我們將定義一個編碼函數,假設code保證是三個 ascii 字符(見注釋)。

from struct import pack, unpack

def encode(row, code_label='code', date_label='date'):
    date_is_ge_20220101 = row[date_label] >= '20220101'
    code_as_bytes = bytes(row[code_label], encoding='ascii')
    return unpack('>I', pack('?3s', date_is_ge_20220101, code_as_bytes))[0]

執行編碼...

df1['encoding'] = df1.apply(encode, axis='columns')
df2['encoding'] = df2.apply(encode, axis='columns',
                                    code_label='range1',
                                    date_label='s_date')

合並時請記住merge_asof需要對合並值進行排序。

pd.merge_asof(df1.sort_values('encoding'),
              df2.sort_values('encoding'),
              on='encoding')

給...

    code date     encoding  range1  range2  s_date   category
0   A51  20211215 4273457   A00     B60     20210101 AA
1   D89  20211215 4470841   D00     D90     20210101 DD
2   A51  20221215 21050673  A00     B99     20220101 A
3   C52  20221215 21181746  C50     C60     20220101 B

鄭重聲明,只有在絕對必要的情況下才能滿足項目的要求,我才會采用這種方法。 它與最初的問題陳述相去甚遠,盡管很有趣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM