Leetcode 解鎖 - Immediate Food Delivery II

更新於 發佈於 閱讀時間約 10 分鐘
raw-image



題目概述

LeetCode 第 1174 題「Immediate Food Delivery II」的目標是計算所有顧客的第一筆訂單中,即時配送(即訂單日期與顧客偏好配送日期相同)的比例,並將結果四捨五入至小數點後兩位。

[問題連結]


Input 格式

資料表名為 Delivery,包含以下欄位:​

raw-image


每筆記錄代表一筆訂單,顧客可以在下單時指定偏好配送日期。

  • delivery_id 是主鍵。
  • 每位顧客可能有多筆訂單。



Output 格式

輸出結果需包含以下欄位:

raw-image

代表顧客中第一筆訂單為即時配送的比例(百分比表示法)。

解釋:

  • 顧客 1 的第一筆訂單是 id=1,是排程(scheduled)
  • 顧客 2 的第一筆訂單是 id=2,是即時(immediate)
  • 顧客 3 的第一筆訂單是 id=5,是排程(scheduled)
  • 顧客 4 的第一筆訂單是 id=7,是即時(immediate)

總共 4 位顧客,2 位為即時 → 比例為 2/4 = 0.550.00


Pandas 解法 1
idxmin精準定位最早訂單

Step 1: 使用 groupby 搭配 idxmin(),根據 customer_id 分組,找出每組中 order_date 最早的索引,進而取得每位顧客的第一筆訂單。

Step 2: 判斷即時配送,比較 order_datecustomer_pref_delivery_date 是否相同,若相同則為即時配送。

Step 3: 計算百分比,統計即時配送的筆數,除以總顧客數,乘以 100,並四捨五入至小數點後兩位。

def immediate_food_delivery(delivery: pd.DataFrame) -> pd.DataFrame:

    first_orders = delivery.loc[delivery.groupby('customer_id')['order_date'].idxmin()]

    immediate_count = (first_orders['order_date'] == first_orders['customer_pref_delivery_date']).sum()

    total_customers = first_orders.shape[0]

    percentage = round(immediate_count * 100 / total_customers, 2)

    return pd.DataFrame({'immediate_percentage': [percentage]})
raw-image



Pandas 解法 2
排好順序直接抽第一筆

Step 1: 排序資料, 將資料依照 customer_idorder_date 進行排序,確保每位顧客的第一筆訂單位於最前面。

Step 2: 去除重複值,使用 drop_duplicates,以 customer_id 為依據,保留每位顧客的第一筆訂單。

Step 3:判斷即時配送並計算百分比,同解法一。


def immediate_food_delivery(delivery: pd.DataFrame) -> pd.DataFrame:

    delivery_sorted = delivery.sort_values(by=['customer_id', 'order_date'])

    first_orders = delivery_sorted.drop_duplicates(subset='customer_id', keep='first')

    immediate_count = (first_orders['order_date'] == first_orders['customer_pref_delivery_date']).sum()

    total_customers = first_orders.shape[0]

    percentage = round(immediate_count * 100 / total_customers, 2)

    return pd.DataFrame({'immediate_percentage': [percentage]})


raw-image



Pandas 解法 2.a
使用 first(),直接取得每位顧客的第一筆訂單。
first_orders = delivery_sorted.groupby('customer_id').first().reset_index()


Pandas 解法 2.b
使用 nth(0),直接取得每位顧客的第一筆訂單。
first_orders = delivery_sorted.groupby('customer_id').nth(0).reset_index()


Pandas 解法 2.c
rank(method='dense') 標記首筆資料
delivery['rnk'] = delivery.groupby('customer_id')['order_date'].rank(method='dense')
first_orders = delivery[delivery['rnk'] == 1]


Pandas 解法 3
使用 groupbymergeagg 的組合技

Step 1: 找出每位顧客的最早訂單日期,使用 groupby 搭配 agg(),取得每位顧客的最早 order_date

Step 2:合併原始資料,將上述結果與原始資料進行合併,取得完整的第一筆訂單資訊。

Step 3:標記即時配送,新增一個 immediate 欄位,若 order_datecustomer_pref_delivery_date 相同,則標記為 1,否則為 0。

Step 4:計算百分比,

  • 使用 agg() 計算即時配送的總數與總配送數,agg() 回傳的是 Series,為了能像表格那樣操作,用 .to_frame() 轉成單欄 DataFrame,再 .T 做轉置,讓每個欄位在橫向呈現。


def immediate_food_delivery(delivery: pd.DataFrame) -> pd.DataFrame:
    first_order = delivery.groupby('customer_id', as_index=False).agg({'order_date': 'min'})

    first_order_info = first_order.merge(delivery, on=['customer_id', 'order_date'])

    first_order_info['immediate'] = (first_order_info['order_date'] == first_order_info['customer_pref_delivery_date']).astype(int)

    df = first_order_info.agg({'immediate': 'sum', 'customer_id': 'nunique'}).to_frame().T

    df['immediate_percentage'] = (df['immediate'] / df['customer_id']) * 100

    return df[['immediate_percentage']].round(2)


raw-image



Pandas 錯誤解法

以下解法看似快速且雖能通過偵錯,但其實不是正確的方法,你可以從第一步發現,對整張表做 .min(),等於是對每一個欄位分別取最小值,因此它們可能來自不同訂單。只是剛好在這個例子的資料集order_date & customer_pref_delivery_date 剛好不會被錯置,意味著這題的資料客戶想要的時間"絕對"不會比下一筆訂單(或配送單)晚。其實你仔細看看回傳的資料就可以發現customer id 3的資料已經有出了問題,回傳的delivery id是4,不是原資料的5,因為這個指令是回傳每個欄位的最小值,不過因為這題delivery id只是迷惑答題人的欄位而已,因此不會在偵錯時被擋住。


def immediate_food_delivery(delivery: pd.DataFrame) -> pd.DataFrame:

    Total = len(df:= delivery.groupby("customer_id").min())

    Immediate = len(df[df.order_date == df.customer_pref_delivery_date])

    return pd.DataFrame({"immediate_percentage": [Immediate / Total *100]}).round(2)


raw-image



謝謝您花時間將此篇文章讀完,若覺得對您有幫助可以幫忙按個讚、分享來或是珍藏喔!也歡迎Follow我的ThreadsFB,持續追蹤生產力工具、商業分析、商業英文的實用範例,提升自己的職場力喔!






avatar-img
DigNo Ape 數遊原人
49會員
117內容數
我們秉持著從原人進化的精神,不斷追求智慧的累積和工具的運用來提升生產力。我們相信,每一個成員都擁有無限的潛力,透過學習和實踐,不斷成長和進步。
留言
avatar-img
留言分享你的想法!
你可能也想看
Google News 追蹤
Thumbnail
【vocus 精選投資理財/金融類沙龍,輸入 "moneyback" 年訂閱 9 折】 市場動盪時,加碼永遠值得的投資標的——「自己」 川普政府再度拋出關稅震撼彈,全球市場應聲重挫,從散戶到專業投資人,都急著找尋買進殺出的訊號,就是現在,輪到知識進場!把握時機讓自己升級,別放過反彈的機會!
Thumbnail
題目概述 LeetCode 第 1174 題「Immediate Food Delivery II」的目標是計算所有顧客的第一筆訂單中,即時配送(即訂單日期與顧客偏好配送日期相同)的比例,並將結果四捨五入至小數點後兩位。 [問題連結]
Thumbnail
題目敘述 Combination Sum II_Leetcode #40 給定一個整數陣列candidates 和 目標值target。 每個陣列元素只能選擇一次,請問有多少種組合方法,可以使得組合數總和 = target? 請把滿足組合數總和 = target的組合方法以陣列的形式返回答案
Thumbnail
題目敘述 Solving Questions With Brainpower 給定一個測驗題陣列,每個欄位都是一個pair, 分別記錄測驗題做完可以得到的分數,和需要的冷卻時間 (也就是會有一段時間不能作答接下來的題目)。 請問在最佳的答題策略下,最多可以獲得多少分數?
Thumbnail
Leetcode 精選75題 題目與題解 熱門考點 目錄 (持續更新中) 建議從左側目錄 或者 按Ctrl+F輸入關鍵字進行搜尋
Thumbnail
題目會給定一個陣列nums和一個目標值goal。計算子陣列總和=goal的數目有多少。演算法包含前綴和和字典的技巧,時間複雜度為O(n),空間複雜度為O(n)。
Thumbnail
題目敘述 題目會給定我們兩個字串。 第一個是指定順序的字串order。 第二個是輸入字串s。 要求我們依據order給定的順序,重新排列s。 如果出現order中沒有出現的字母,任意位置皆可。 合法答案可能不只一組,輸出其中一種即可。 題目的原文敘述 測試範例 Example
Thumbnail
題目敘述 題目會給我們一個定義好的類別和function介面,要求我們實作建構子和ping() function來滿足指定的需求。 RecentCounter類別的建構子 建構子應該初始化來電紀錄,內容為空(零筆資料) int ping(int t) t代表來電時刻,單位是毫秒m
Thumbnail
題目敘述 題目會給定兩個輸入。 第一個輸入是關鍵字清單products,第二個是使用者輸入的字串searchWord。 要求我們實現關鍵字搜尋建議系統,使用者每輸入一個字元就推薦一次。 推薦時,優先返回字典序(Lecial order)最接近的關鍵字,最多不要超過三個關鍵字。 題目的原文
Thumbnail
題目會給定一個輸入陣列temperatures ,分別代表每一天的溫度。 請計算每一天還要再過幾天才會遇到更溫暖的日子,如果遇不到,則回填0。 請以陣列的形式返回答案。 題目的原文敘述 約束條件 Constraints: 1 <= temperatures.length <= 10^
Thumbnail
題目敘述 給定兩個字串word1和word2,每次操作時,可以有三個選項 插入一個字元 刪除一個字元 替換一個字元 請問把word1轉換成word2的最小操作次數是多少? 題目的原文敘述 約束條件 Constraints: 0 <= word1.length, word2.le
Thumbnail
【vocus 精選投資理財/金融類沙龍,輸入 "moneyback" 年訂閱 9 折】 市場動盪時,加碼永遠值得的投資標的——「自己」 川普政府再度拋出關稅震撼彈,全球市場應聲重挫,從散戶到專業投資人,都急著找尋買進殺出的訊號,就是現在,輪到知識進場!把握時機讓自己升級,別放過反彈的機會!
Thumbnail
題目概述 LeetCode 第 1174 題「Immediate Food Delivery II」的目標是計算所有顧客的第一筆訂單中,即時配送(即訂單日期與顧客偏好配送日期相同)的比例,並將結果四捨五入至小數點後兩位。 [問題連結]
Thumbnail
題目敘述 Combination Sum II_Leetcode #40 給定一個整數陣列candidates 和 目標值target。 每個陣列元素只能選擇一次,請問有多少種組合方法,可以使得組合數總和 = target? 請把滿足組合數總和 = target的組合方法以陣列的形式返回答案
Thumbnail
題目敘述 Solving Questions With Brainpower 給定一個測驗題陣列,每個欄位都是一個pair, 分別記錄測驗題做完可以得到的分數,和需要的冷卻時間 (也就是會有一段時間不能作答接下來的題目)。 請問在最佳的答題策略下,最多可以獲得多少分數?
Thumbnail
Leetcode 精選75題 題目與題解 熱門考點 目錄 (持續更新中) 建議從左側目錄 或者 按Ctrl+F輸入關鍵字進行搜尋
Thumbnail
題目會給定一個陣列nums和一個目標值goal。計算子陣列總和=goal的數目有多少。演算法包含前綴和和字典的技巧,時間複雜度為O(n),空間複雜度為O(n)。
Thumbnail
題目敘述 題目會給定我們兩個字串。 第一個是指定順序的字串order。 第二個是輸入字串s。 要求我們依據order給定的順序,重新排列s。 如果出現order中沒有出現的字母,任意位置皆可。 合法答案可能不只一組,輸出其中一種即可。 題目的原文敘述 測試範例 Example
Thumbnail
題目敘述 題目會給我們一個定義好的類別和function介面,要求我們實作建構子和ping() function來滿足指定的需求。 RecentCounter類別的建構子 建構子應該初始化來電紀錄,內容為空(零筆資料) int ping(int t) t代表來電時刻,單位是毫秒m
Thumbnail
題目敘述 題目會給定兩個輸入。 第一個輸入是關鍵字清單products,第二個是使用者輸入的字串searchWord。 要求我們實現關鍵字搜尋建議系統,使用者每輸入一個字元就推薦一次。 推薦時,優先返回字典序(Lecial order)最接近的關鍵字,最多不要超過三個關鍵字。 題目的原文
Thumbnail
題目會給定一個輸入陣列temperatures ,分別代表每一天的溫度。 請計算每一天還要再過幾天才會遇到更溫暖的日子,如果遇不到,則回填0。 請以陣列的形式返回答案。 題目的原文敘述 約束條件 Constraints: 1 <= temperatures.length <= 10^
Thumbnail
題目敘述 給定兩個字串word1和word2,每次操作時,可以有三個選項 插入一個字元 刪除一個字元 替換一個字元 請問把word1轉換成word2的最小操作次數是多少? 題目的原文敘述 約束條件 Constraints: 0 <= word1.length, word2.le