簡體   English   中英

match語句python3.10中的條件情況(結構模式匹配)

[英]Conditional cases in match statement python3.10 (structural pattern matching)

我目前正在開發一些東西,想知道 python 3.10 中的新匹配語句是否適合這樣的用例,我有條件語句。

作為輸入,我有一個時間戳和一個帶有日期和值的 dataframe。 目標是遍歷所有行,並根據日期將值添加到相應的 bin bases。 在這里,將值放置在哪個 bin 中取決於與時間戳相關的日期。 時間戳 1 個月內的日期放在 bin 1 中,2 個月內放在 bin 2 中,依此類推...

我現在的代碼如下:

bins = [0] * 7

for date, value in zip(df.iloc[:,0],df.iloc[:,1]):
    match [date,value]:
        case [date,value] if date < timestamp + pd.Timedelta(1,'m'):
            bins[0] += value
        case [date,value] if date > timestamp + pd.Timedelta(1,'m') and date < timestamp + pd.Timedelta(2,'m'):
            bins[1] += value
        case [date,value] if date > timestamp + pd.Timedelta(2,'m') and date < timestamp + pd.Timedelta(3,'m'):
            bins[2] += value
        case [date,value] if date > timestamp + pd.Timedelta(3,'m') and date < timestamp + pd.Timedelta(4,'m'):
            bins[3] += value
        case [date,value] if date > timestamp + pd.Timedelta(4,'m') and date < timestamp + pd.Timedelta(5,'m'):
            bins[4] += value
        case [date,value] if date > timestamp + pd.Timedelta(5,'m') and date < timestamp + pd.Timedelta(6,'m'):
            bins[5] += value

更正:最初我聲明此代碼不起作用。 事實證明它確實如此。 但是,我仍然想知道這是否適合使用 match 語句。

我會說這不是結構模式匹配的好用,因為沒有實際的結構 您正在檢查單個 object 的,因此 if/elif 鏈是一個更好、更具可讀性和自然的選擇。

我對你寫的方式還有 2 個問題-

  1. 您不考慮垃圾箱邊緣的值
  2. 你正在檢查相同的條件兩次,即使你達到了一些匹配/案例的檢查,你保證以前的不匹配 - 所以你不需要做if date > timestamp + pd.Timedelta(1,'m') and...如果先前檢查if date < timestamp + pd.Timedelta(1,'m')失敗,您已經知道它並不小。 (存在平等的邊緣情況,但無論如何都應該以某種方式處理)

總而言之,我認為這將是更清潔的解決方案:

for date, value in zip(df.iloc[:,0],df.iloc[:,1]):

    if date < timestamp + pd.Timedelta(1,'m'):
        bins[0] += value
    elif date < timestamp + pd.Timedelta(2,'m'):
        bins[1] += value
    elif date < timestamp + pd.Timedelta(3,'m'):
        bins[2] += value
    elif date < timestamp + pd.Timedelta(4,'m'):
        bins[3] += value
    elif date < timestamp + pd.Timedelta(5,'m'):
        bins[4] += value
    elif date < timestamp + pd.Timedelta(6,'m'):
        bins[5] += value
    else:
        pass

這真的應該直接用 Pandas 函數來完成:

import pandas as pd
from datetime import datetime

timestamp = datetime.now()
bins = [pd.Timestamp(year=1970, month=1, day=1)]+[pd.Timestamp(timestamp)+pd.Timedelta(i, 'm') for i in range(6)]+[pd.Timestamp(year=2100, month=1, day=1)] # plus open bin on the right
n_samples = 1000

data = {
  'date': [pd.to_datetime(timestamp)+pd.Timedelta(i,'s') for i in range(n_samples)],
  'value': list(range(n_samples))
}

df = pd.DataFrame(data)

df['bin'] = pd.cut(df.date, bins, right=False)
df.groupby('bin').value.sum()

暫無
暫無

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

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