From d496078b6f2674e0be853a64c18b1fb750a81e09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E5=86=A0=E5=BB=B7?= Date: Sun, 3 May 2026 16:37:24 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E5=AE=8C=E6=88=90=20M1=20=E4=BD=9C?= =?UTF-8?q?=E6=A5=AD=20-=E5=91=A8=E5=86=A0=E5=BB=B7=20-AIPE03?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- homework/m1_numpy.py | 47 ++++++++++++++++++---- homework/m2_pandas_cleaning.py | 49 +++++++++++++++++++---- homework/m3_pandas_advanced.py | 39 +++++++++++++++---- homework/m4_timeseries.py | 42 ++++++++++++++++---- homework/m5_visualization.py | 67 ++++++++++++++++++++++++++++---- homework/m6_plotly_capstone.py | 71 ++++++++++++++++++++++++++++++---- 6 files changed, 270 insertions(+), 45 deletions(-) diff --git a/homework/m1_numpy.py b/homework/m1_numpy.py index 5ff41ab..76719c0 100644 --- a/homework/m1_numpy.py +++ b/homework/m1_numpy.py @@ -19,20 +19,26 @@ def green_mean(): """建立 [10, 20, 30, 40, 50],回傳所有元素的平均值 (float)""" # TODO: 你的程式碼 - pass + arr = np.mean([10, 20, 30, 40, 50]) + result = arr + return result + def green_double(): """建立 [10, 20, 30, 40, 50],回傳所有元素乘以 2 的 ndarray""" # TODO: 你的程式碼 - pass + arr = np.array([10, 20, 30, 40, 50]) + result = arr * 2 + return result def green_filter(): """建立 [10, 20, 30, 40, 50],回傳大於 25 的元素 (ndarray)""" # TODO: 你的程式碼 - pass - + arr = np.array([10, 20, 30, 40, 50]) + result = arr[arr > 25] + return result # ============================================================ # 🟡 核心題(每題 15 分,共 45 分) @@ -42,7 +48,10 @@ def green_filter(): def yellow_expensive_count(prices): """回傳單價 > 1000 的商品數量 (int)""" # TODO: 你的程式碼 - pass + DATA = '../datasets/products.csv' + unit_price = np.genfromtxt(DATA, delimiter=',', skip_header=1, usecols=3) + result = len(unit_price[unit_price > 1000]) + return (result) def yellow_top3_stock_indices(stocks): @@ -51,7 +60,11 @@ def yellow_top3_stock_indices(stocks): 提示:np.argsort """ # TODO: 你的程式碼 - pass + DATA = '../datasets/ecommerce/products.csv' + qty_stock = np.genfromtxt(DATA, delimiter=',', skip_header=1, usecols=4) + result = np.argsort(qty_stock) + top3_stock = result[::-1][:3] + return top3_stock def yellow_restock_cost(prices, stocks): @@ -60,8 +73,13 @@ def yellow_restock_cost(prices, stocks): 提示:布林遮罩 + .sum() """ # TODO: 你的程式碼 - pass + DATA = '../datasets/ecommerce/products.csv' + unit_price = np.genfromtxt(DATA, delimiter=',', skip_header=1, usecols=3) + qty_stock = np.genfromtxt(DATA, delimiter=',', skip_header=1, usecols=4) + lower_500 = unit_price[np.array(unit_price < 500)] + total_price = lower_500.sum()* 50 + return total_price # ============================================================ # 🔴 挑戰題(25 分) @@ -77,4 +95,17 @@ def red_double11_prices(prices, stocks): 提示:np.where 可以巢狀使用 """ # TODO: 你的程式碼 - pass + DATA = '../datasets/ecommerce/products.csv' + price = np.genfromtxt(DATA, delimiter=',', skip_header=1, usecols=3) + stock = np.genfromtxt(DATA, delimiter=',', skip_header=1, usecols=4) + + final_price = np.where( + stock >= 100, + price * 0.7, + np.where( + stock >= 20, + price * 0.9, + price + ) +) + return final_price diff --git a/homework/m2_pandas_cleaning.py b/homework/m2_pandas_cleaning.py index fa36bff..1a9bdba 100644 --- a/homework/m2_pandas_cleaning.py +++ b/homework/m2_pandas_cleaning.py @@ -9,18 +9,20 @@ """ import pandas as pd - # ============================================================ # 🟢 送分題(每題 10 分,共 30 分) # ============================================================ +DATA = '../datasets/ecommerce/orders_raw.csv' +df = pd.read_csv(DATA) + def green_read_csv(): """ 讀取 orders_raw.csv,回傳原始 DataFrame(不做任何清理) 提示:pd.read_csv() """ # TODO: 你的程式碼 - pass + return df def green_shape(df): @@ -29,7 +31,8 @@ def green_shape(df): 提示:df.shape """ # TODO: 你的程式碼 - pass + return df.shape + def green_dtypes(df): @@ -38,7 +41,7 @@ def green_dtypes(df): 提示:df.dtypes """ # TODO: 你的程式碼 - pass + return df.dtypes # ============================================================ @@ -52,7 +55,9 @@ def yellow_clean_columns(df): 提示:df.columns.str.strip().str.lower() """ # TODO: 你的程式碼 - pass + new_df = df.copy() + new_df.columns = new_df.columns.str.strip().str.lower() + return new_df.columns def yellow_clean_amount(df): @@ -63,7 +68,15 @@ def yellow_clean_amount(df): 提示:.str.replace() + .astype(float) """ # TODO: 你的程式碼 - pass + df_copy = df.copy() # 複製一份 + df_copy['amount']=( + df_copy['amount'] + .astype(str) + .str.replace('$', '', regex = False) + .str.replace(',', '', regex = False) + .astype(float) + ) + return df_copy # 整張清理過的表 def yellow_drop_duplicates(df): @@ -72,7 +85,8 @@ def yellow_drop_duplicates(df): 提示:df.drop_duplicates() """ # TODO: 你的程式碼 - pass + df_drop = df.drop_duplicates() + return df_drop # ============================================================ @@ -93,4 +107,23 @@ def red_clean_orders(path): 提示:pd.to_datetime(errors='coerce') """ # TODO: 你的程式碼 - pass + df = pd.read_csv(path) # 1 + + df.columns = df.columns.str.strip().str.lower() # 2 + + df['amount']=( + df['amount'] + .astype(str) + .str.replace('$', '', regex = False) + .str.replace(',', '', regex = False) + .astype(float) + ) # 3 + + df['order_date'] = pd.to_datetime(df['order_date'], errors = 'coerce') # 4 + + df = df.dropna(subset = ['amount','order_date']) # 5 + + df_drop = df.drop_duplicates() # 6 + df = df_drop + return df + diff --git a/homework/m3_pandas_advanced.py b/homework/m3_pandas_advanced.py index 68410e8..7b0b18d 100644 --- a/homework/m3_pandas_advanced.py +++ b/homework/m3_pandas_advanced.py @@ -15,6 +15,11 @@ # ============================================================ # 🟢 送分題(每題 10 分,共 30 分) # ============================================================ +order = pd.read_csv('..\datasets\ecommerce\orders_clean.csv') +customers = pd.read_csv('..\datasets\ecommerce\customers.csv') +products = pd.read_csv('..\datasets\ecommerce\products.csv') + + def green_load_and_merge(): """ @@ -24,19 +29,22 @@ def green_load_and_merge(): 提示:pd.merge(how='left') """ # TODO: 你的程式碼 - pass + oc = order.merge(customers, on = 'customer_id',how = 'left' ) + df = oc.merge(products, on = 'product_id', how = 'left') + return df def green_row_count(df): """回傳 DataFrame 的列數 (int)""" # TODO: 你的程式碼 - pass - + count = df.shape[0] + return count def green_column_list(df): """回傳 DataFrame 的所有欄位名稱 (list)""" # TODO: 你的程式碼 - pass + column_names = df.columns.tolist() + return column_names # ============================================================ @@ -50,7 +58,8 @@ def yellow_top_category(df): 提示:groupby('category')['amount'].sum() """ # TODO: 你的程式碼 - pass + category_rev = df.groupby('category')['amount'].sum().idxmax() + return category_rev def yellow_gold_vip_stats(df): @@ -60,7 +69,10 @@ def yellow_gold_vip_stats(df): 提示:df[df['vip_level'] == 'Gold'] """ # TODO: 你的程式碼 - pass + gold_df = df[df['vip_level'] == 'Gold'] + order_count = len(gold_df) # 數出vip是gold等級的有幾張訂單 + gold_amount = gold_df['amount'].sum() + return (int(order_count), float(gold_amount)) def yellow_region_avg_amount(df): @@ -70,7 +82,8 @@ def yellow_region_avg_amount(df): 提示:groupby('region')['amount'].mean() """ # TODO: 你的程式碼 - pass + region_avg = df.groupby('region')['amount'].mean() + return region_avg # ============================================================ @@ -94,4 +107,14 @@ def red_rfm_top5(df): 提示:groupby('customer_id').agg(...) """ # TODO: 你的程式碼 - pass + rfm = df.groupby(['customer_id', 'customer_name']).agg({ + 'order_date': 'max', + 'order_id': 'count', + 'amount': 'sum' + }).reset_index() + + rfm.columns = ['customer_id', 'customer_name', 'R', 'F', 'M'] + + top5 = rfm.sort_values(by='M', ascending=False).head(5) + + return top5 diff --git a/homework/m4_timeseries.py b/homework/m4_timeseries.py index 047af6a..ae8e196 100644 --- a/homework/m4_timeseries.py +++ b/homework/m4_timeseries.py @@ -27,7 +27,9 @@ def green_avg_by_month(): 提示:df['order_date'].dt.month """ # TODO: 你的程式碼 - pass + df = _load_data() + mon_avg = df.groupby(df['order_date'].dt.month)['amount'].mean() + return mon_avg def green_top3_dates(): @@ -37,7 +39,9 @@ def green_top3_dates(): 提示:value_counts().head(3) """ # TODO: 你的程式碼 - pass + df = _load_data() + result = df['order_id'].value_counts().head(3) + return result def green_date_range(): @@ -46,7 +50,11 @@ def green_date_range(): 格式為 pandas Timestamp """ # TODO: 你的程式碼 - pass + df = _load_data() + earliest = df['order_date'].min() + latest = df['order_date'].max() + + return (earliest, latest) # ============================================================ @@ -60,7 +68,9 @@ def yellow_monthly_revenue(): 提示:set_index('order_date').resample('ME')['amount'].sum() """ # TODO: 你的程式碼 - pass + df = _load_data() + monthly_revenue = df.set_index('order_date').resample('ME')['amount'].sum() + return monthly_revenue def yellow_rolling_avg(monthly_revenue): @@ -71,7 +81,8 @@ def yellow_rolling_avg(monthly_revenue): 提示:.rolling(window=3).mean() """ # TODO: 你的程式碼 - pass + rolling_avg = monthly_revenue.rolling(window=3).mean() + return rolling_avg def yellow_category_median(df): @@ -81,7 +92,9 @@ def yellow_category_median(df): 提示:groupby + median + sort_values """ # TODO: 你的程式碼 - pass + df = _load_data() + category_med = df.groupby('category')['amount'].median().sort_values(ascending=False) + return category_med # ============================================================ @@ -101,4 +114,19 @@ def red_monthly_report(): 提示:resample + agg + pct_change """ # TODO: 你的程式碼 - pass + df = _load_data + temp_df = df.set_index('order_date') + + report = temp_df.resample('ME').agg({ + 'order_id': 'count', + 'amount': 'sum', + 'customer_id': 'nunique' + }) + + report.columns = ['order_count', 'revenue', 'active_customers'] + + report['avg_order_value'] = report['revenue'] / report['order_count'] + + report['revenue_growth'] = report['revenue'].pct_change() + + return report diff --git a/homework/m5_visualization.py b/homework/m5_visualization.py index 7e7335d..8e7909b 100644 --- a/homework/m5_visualization.py +++ b/homework/m5_visualization.py @@ -29,7 +29,10 @@ def green_bar_category(): 提示:sns.countplot 或 value_counts().plot.bar() """ # TODO: 你的程式碼 - pass + df = _load_data() + fig, ax = plt.subplots() + sns.countplot(x='category', data=df, ax=ax) + return fig def green_hist_amount(): @@ -39,7 +42,10 @@ def green_hist_amount(): 提示:sns.histplot(bins=20) 或 plt.hist() """ # TODO: 你的程式碼 - pass + df = _load_data() + fig, ax = plt.subplots() + sns.histplot(df['amount'], bins=20, ax=ax) + return fig def green_set_labels(): @@ -51,7 +57,13 @@ def green_set_labels(): 回傳 matplotlib Figure 物件 """ # TODO: 你的程式碼 - pass + df = _load_data() + fig, ax = plt.subplots() + df['category'].value_counts().plot(kind='bar', ax=ax) + ax.set_title("Order Count by Category") + ax.set_xlabel("Product Category") + ax.set_ylabel("Number of Orders") + return fig # ============================================================ @@ -68,7 +80,14 @@ def yellow_line_region_trend(): 提示:分別 groupby 再 plot,或用 sns.lineplot(hue='region') """ # TODO: 你的程式碼 - pass + df = _load_data() + df['month'] = df['order_date'].dt.to_period('M').astype(str) + trend = df[df['region'].isin(['North', 'South'])].groupby(['month', 'region'])['amount'].sum().reset_index() + + fig, ax = plt.subplots(figsize=(10, 6)) + sns.lineplot(x='month', y='amount', hue='region', data=trend, ax=ax) + plt.xticks(rotation=45) + return fig def yellow_box_vip(): @@ -78,7 +97,10 @@ def yellow_box_vip(): 提示:sns.boxplot(x='vip_level', y='amount', data=df) """ # TODO: 你的程式碼 - pass + df = _load_data() + fig, ax = plt.subplots() + sns.boxplot(x='vip_level', y='amount', data=df, ax=ax) + return fig def yellow_scatter_price_amount(): @@ -88,7 +110,10 @@ def yellow_scatter_price_amount(): 提示:plt.scatter() 或 sns.scatterplot() """ # TODO: 你的程式碼 - pass + df = _load_data() + fig, ax = plt.subplots() + sns.scatterplot(x='unit_price', y='amount', data=df, ax=ax) + return fig # ============================================================ @@ -107,4 +132,32 @@ def red_category_dashboard(category="Electronics"): 提示:fig, axes = plt.subplots(2, 2, figsize=(14, 10)) """ # TODO: 你的程式碼 - pass + df = _load_data() + target_df = df[df['category'] == category].copy() + target_df['month'] = target_df['order_date'].dt.to_period('M').astype(str) + + + fig, axes = plt.subplots(2, 2, figsize=(14, 10)) + fig.suptitle(f"Dashboard: {category}", fontsize=20) + + + monthly_rev = target_df.groupby('month')['amount'].sum() + monthly_rev.plot(ax=axes[0, 0], marker='o') + axes[0, 0].set_title("Monthly Revenue Trend") + + + region_rev = target_df.groupby('region')['amount'].sum() + region_rev.plot(kind='bar', ax=axes[0, 1]) + axes[0, 1].set_title("Revenue by Region") + + + top5 = target_df.groupby('product_name')['amount'].sum().sort_values(ascending=False).head(5) + top5.plot(kind='barh', ax=axes[1, 0]) + axes[1, 0].set_title("Top 5 Products") + + + sns.histplot(target_df['amount'], bins=15, ax=axes[1, 1]) + axes[1, 1].set_title("Order Amount Distribution") + + plt.tight_layout(rect=[0, 0.03, 1, 0.95]) + return fig diff --git a/homework/m6_plotly_capstone.py b/homework/m6_plotly_capstone.py index 0e2c32a..405b4bf 100644 --- a/homework/m6_plotly_capstone.py +++ b/homework/m6_plotly_capstone.py @@ -26,7 +26,13 @@ def green_plotly_bar(): 提示:px.bar() """ # TODO: 你的程式碼 - pass + + df = pd.read_csv("datasets/ecommerce/orders_enriched.csv") + + rev_by_cat = df.groupby('category')['amount'].sum().reset_index() + + fig = px.bar(rev_by_cat, x='category', y='amount', title="Revenue by Category") + return fig def green_plotly_line(): @@ -37,7 +43,12 @@ def green_plotly_line(): 提示:先 groupby 月份算總營收,再 px.line() """ # TODO: 你的程式碼 - pass + df = pd.read_csv("datasets/ecommerce/orders_enriched.csv", parse_dates=["order_date"]) + + monthly_rev = df.set_index('order_date').resample('ME')['amount'].sum().reset_index() + + fig = px.line(monthly_rev, x='order_date', y='amount', title="Monthly Revenue Trend") + return fig def green_plotly_pie(): @@ -48,7 +59,10 @@ def green_plotly_pie(): 提示:px.pie() """ # TODO: 你的程式碼 - pass + df = pd.read_csv("datasets/ecommerce/orders_enriched.csv") + + fig = px.pie(df, names='vip_level', title="VIP Order Distribution") + return fig # ============================================================ @@ -63,7 +77,15 @@ def yellow_clean_and_merge(raw_path, customers_path, products_path): 回傳:合併後的 DataFrame """ # TODO: 你的程式碼 - pass + orders = pd.read_csv(raw_path, parse_dates=["order_date"]) + orders = orders.dropna().drop_duplicates() # 去缺值與重複 + + customers = pd.read_csv(customers_path) + products = pd.read_csv(products_path) + + df = orders.merge(customers, on='customer_id', how='left') + df = df.merge(products, on='product_id', how='left') + return df def yellow_kpi_summary(df): @@ -77,7 +99,13 @@ def yellow_kpi_summary(df): } """ # TODO: 你的程式碼 - pass + kpi = { + "total_revenue": float(df['amount'].sum()), + "order_count": int(df['order_id'].nunique()), + "active_customers": int(df['customer_id'].nunique()), + "avg_order_value": float(df['amount'].sum() / df['order_id'].nunique()) + } + return kpi def yellow_plotly_scatter(df): @@ -91,7 +119,9 @@ def yellow_plotly_scatter(df): 提示:px.scatter(hover_data=['product_name']) """ # TODO: 你的程式碼 - pass + fig = px.scatter(df, x='unit_price', y='amount', color='category', + hover_data=['product_name'], title="Price vs Amount") + return fig # ============================================================ @@ -115,4 +145,31 @@ def red_dashboard(): 提示:from plotly.subplots import make_subplots """ # TODO: 你的程式碼 - pass + df = yellow_clean_and_merge( + "datasets/ecommerce/orders_raw.csv", + "datasets/ecommerce/customers.csv", + "datasets/ecommerce/products.csv" + ) + + # 2. 準備 2x2 畫布,並設定子圖類型 (pie 圖需要特別設定 type='domain') + fig = make_subplots( + rows=2, cols=2, + subplot_titles=("Monthly Revenue", "Top 10 Products", "Region Revenue", "Category Share"), + specs=[[{"type": "xy"}, {"type": "xy"}], + [{"type": "xy"}, {"type": "domain"}]] + ) + + m_rev = df.set_index('order_date').resample('ME')['amount'].sum().reset_index() + fig.add_trace(go.Scatter(x=m_rev['order_date'], y=m_rev['amount'], name="Revenue"), row=1, col=1) + + top10 = df.groupby('product_name')['amount'].sum().sort_values(ascending=False).head(10) + fig.add_trace(go.Bar(x=top10.index, y=top10.values, name="Top Products"), row=1, col=2) + + reg_rev = df.groupby('region')['amount'].sum() + fig.add_trace(go.Bar(x=reg_rev.index, y=reg_rev.values, name="Region"), row=2, col=1) + + cat_rev = df.groupby('category')['amount'].sum() + fig.add_trace(go.Pie(labels=cat_rev.index, values=cat_rev.values), row=2, col=2) + + fig.update_layout(height=800, title_text="E-commerce Executive Dashboard", showlegend=False) + return fig \ No newline at end of file From b6176ce8762c520a2f6cc4e547ff96976514cf16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E5=86=A0=E5=BB=B7?= Date: Sun, 3 May 2026 16:59:19 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E5=AE=8C=E6=88=90M1=E4=BD=9C=E6=A5=AD=20-?= =?UTF-8?q?=E5=91=A8=E5=86=A0=E5=BB=B7=20AIPE03?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- homework/m1_numpy.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/homework/m1_numpy.py b/homework/m1_numpy.py index 76719c0..db3bd7c 100644 --- a/homework/m1_numpy.py +++ b/homework/m1_numpy.py @@ -20,8 +20,7 @@ def green_mean(): """建立 [10, 20, 30, 40, 50],回傳所有元素的平均值 (float)""" # TODO: 你的程式碼 arr = np.mean([10, 20, 30, 40, 50]) - result = arr - return result + return arr @@ -29,16 +28,15 @@ def green_double(): """建立 [10, 20, 30, 40, 50],回傳所有元素乘以 2 的 ndarray""" # TODO: 你的程式碼 arr = np.array([10, 20, 30, 40, 50]) - result = arr * 2 - return result + return arr * 2 def green_filter(): """建立 [10, 20, 30, 40, 50],回傳大於 25 的元素 (ndarray)""" # TODO: 你的程式碼 arr = np.array([10, 20, 30, 40, 50]) - result = arr[arr > 25] - return result + return arr[arr > 25] + # ============================================================ # 🟡 核心題(每題 15 分,共 45 分) From e77af12f9d42bcec97801644f36413818ee440ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E5=86=A0=E5=BB=B7?= Date: Sun, 3 May 2026 17:11:59 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E5=AE=8C=E6=88=90M1=5F2=E4=BD=9C=E6=A5=AD?= =?UTF-8?q?=20-=E5=91=A8=E5=86=A0=E5=BB=B7=20AIPE03?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- homework/m1_numpy.py | 42 ++++++++++-------------------------------- 1 file changed, 10 insertions(+), 32 deletions(-) diff --git a/homework/m1_numpy.py b/homework/m1_numpy.py index db3bd7c..567d99c 100644 --- a/homework/m1_numpy.py +++ b/homework/m1_numpy.py @@ -46,11 +46,8 @@ def green_filter(): def yellow_expensive_count(prices): """回傳單價 > 1000 的商品數量 (int)""" # TODO: 你的程式碼 - DATA = '../datasets/products.csv' - unit_price = np.genfromtxt(DATA, delimiter=',', skip_header=1, usecols=3) - result = len(unit_price[unit_price > 1000]) - return (result) - + return (prices > 1000).sum() + def yellow_top3_stock_indices(stocks): """ @@ -58,12 +55,7 @@ def yellow_top3_stock_indices(stocks): 提示:np.argsort """ # TODO: 你的程式碼 - DATA = '../datasets/ecommerce/products.csv' - qty_stock = np.genfromtxt(DATA, delimiter=',', skip_header=1, usecols=4) - result = np.argsort(qty_stock) - top3_stock = result[::-1][:3] - return top3_stock - + return np.argsort(stocks)[::-1][:3] def yellow_restock_cost(prices, stocks): """ @@ -71,13 +63,8 @@ def yellow_restock_cost(prices, stocks): 提示:布林遮罩 + .sum() """ # TODO: 你的程式碼 - DATA = '../datasets/ecommerce/products.csv' - unit_price = np.genfromtxt(DATA, delimiter=',', skip_header=1, usecols=3) - qty_stock = np.genfromtxt(DATA, delimiter=',', skip_header=1, usecols=4) - - lower_500 = unit_price[np.array(unit_price < 500)] - total_price = lower_500.sum()* 50 - return total_price + mask = prices < 500 + return prices[mask].sum() * 50 # ============================================================ # 🔴 挑戰題(25 分) @@ -93,17 +80,8 @@ def red_double11_prices(prices, stocks): 提示:np.where 可以巢狀使用 """ # TODO: 你的程式碼 - DATA = '../datasets/ecommerce/products.csv' - price = np.genfromtxt(DATA, delimiter=',', skip_header=1, usecols=3) - stock = np.genfromtxt(DATA, delimiter=',', skip_header=1, usecols=4) - - final_price = np.where( - stock >= 100, - price * 0.7, - np.where( - stock >= 20, - price * 0.9, - price - ) -) - return final_price + return np.where( + stocks >= 100, + prices * 0.7, + np.where(stocks >= 20, prices * 0.9, prices) + ) \ No newline at end of file From cfda58fe726d9b6ff670c9b468c93e6672fab3d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E5=86=A0=E5=BB=B7?= Date: Sun, 3 May 2026 17:32:43 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E4=BD=9C=E6=A5=AD=E7=B9=B3=E4=BA=A4M1=5F3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- homework/m1_numpy.py | 54 +++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/homework/m1_numpy.py b/homework/m1_numpy.py index 567d99c..327c743 100644 --- a/homework/m1_numpy.py +++ b/homework/m1_numpy.py @@ -19,24 +19,24 @@ def green_mean(): """建立 [10, 20, 30, 40, 50],回傳所有元素的平均值 (float)""" # TODO: 你的程式碼 - arr = np.mean([10, 20, 30, 40, 50]) - return arr - + arr = np.array([10, 20, 30, 40, 50]) + return arr.mean() def green_double(): """建立 [10, 20, 30, 40, 50],回傳所有元素乘以 2 的 ndarray""" # TODO: 你的程式碼 arr = np.array([10, 20, 30, 40, 50]) - return arr * 2 + result = arr * 2 + return result def green_filter(): """建立 [10, 20, 30, 40, 50],回傳大於 25 的元素 (ndarray)""" # TODO: 你的程式碼 arr = np.array([10, 20, 30, 40, 50]) - return arr[arr > 25] - + result = arr[arr > 25] + return result # ============================================================ # 🟡 核心題(每題 15 分,共 45 分) @@ -46,8 +46,11 @@ def green_filter(): def yellow_expensive_count(prices): """回傳單價 > 1000 的商品數量 (int)""" # TODO: 你的程式碼 - return (prices > 1000).sum() - + DATA = '../datasets/products.csv' + unit_price = np.genfromtxt(DATA, delimiter=',', skip_header=1, usecols=3) + result = len(unit_price[unit_price > 1000]) + return (result) + def yellow_top3_stock_indices(stocks): """ @@ -55,7 +58,12 @@ def yellow_top3_stock_indices(stocks): 提示:np.argsort """ # TODO: 你的程式碼 - return np.argsort(stocks)[::-1][:3] + DATA = '../datasets/ecommerce/products.csv' + qty_stock = np.genfromtxt(DATA, delimiter=',', skip_header=1, usecols=4) + result = np.argsort(qty_stock) + top3_stock = result[::-1][:3] + return top3_stock + def yellow_restock_cost(prices, stocks): """ @@ -63,8 +71,13 @@ def yellow_restock_cost(prices, stocks): 提示:布林遮罩 + .sum() """ # TODO: 你的程式碼 - mask = prices < 500 - return prices[mask].sum() * 50 + DATA = '../datasets/ecommerce/products.csv' + unit_price = np.genfromtxt(DATA, delimiter=',', skip_header=1, usecols=3) + qty_stock = np.genfromtxt(DATA, delimiter=',', skip_header=1, usecols=4) + + lower_500 = unit_price[np.array(unit_price < 500)] + total_price = lower_500.sum()* 50 + return total_price # ============================================================ # 🔴 挑戰題(25 分) @@ -80,8 +93,17 @@ def red_double11_prices(prices, stocks): 提示:np.where 可以巢狀使用 """ # TODO: 你的程式碼 - return np.where( - stocks >= 100, - prices * 0.7, - np.where(stocks >= 20, prices * 0.9, prices) - ) \ No newline at end of file + DATA = '../datasets/ecommerce/products.csv' + price = np.genfromtxt(DATA, delimiter=',', skip_header=1, usecols=3) + stock = np.genfromtxt(DATA, delimiter=',', skip_header=1, usecols=4) + + final_price = np.where( + stock >= 100, + price * 0.7, + np.where( + stock >= 20, + price * 0.9, + price + ) +) + return final_price From fa0c4752541eb7ef2f8605d4068ed7c7bb8f4567 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=91=A8=E5=86=A0=E5=BB=B7?= Date: Sun, 3 May 2026 17:54:02 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E4=BD=9C=E6=A5=AD=E7=B9=B3=E4=BA=A4=20=5F4?= =?UTF-8?q?=20-=E5=91=A8=E5=86=A0=E5=BB=B7=20-AIPE03?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- homework/m1_numpy.py | 46 +++++++++++--------------------------------- 1 file changed, 11 insertions(+), 35 deletions(-) diff --git a/homework/m1_numpy.py b/homework/m1_numpy.py index 327c743..a90c236 100644 --- a/homework/m1_numpy.py +++ b/homework/m1_numpy.py @@ -11,7 +11,6 @@ """ import numpy as np - # ============================================================ # 🟢 送分題(每題 10 分,共 30 分) # ============================================================ @@ -43,13 +42,14 @@ def green_filter(): # 以下函式會接收從 products.csv 讀出的 prices, stocks 陣列 # ============================================================ +# ---------- 載入 products.csv ---------- +DATA_PATH = "datasets/ecommerce/products.csv" +prices = np.genfromtxt(DATA_PATH, delimiter=",", skip_header=1, usecols=3) +stocks = np.genfromtxt(DATA_PATH, delimiter=",", skip_header=1, usecols=4) + def yellow_expensive_count(prices): """回傳單價 > 1000 的商品數量 (int)""" - # TODO: 你的程式碼 - DATA = '../datasets/products.csv' - unit_price = np.genfromtxt(DATA, delimiter=',', skip_header=1, usecols=3) - result = len(unit_price[unit_price > 1000]) - return (result) + return prices[prices>1000].size def yellow_top3_stock_indices(stocks): @@ -57,12 +57,7 @@ def yellow_top3_stock_indices(stocks): 回傳庫存最多的前 3 個商品的索引位置 (ndarray, 由大到小排) 提示:np.argsort """ - # TODO: 你的程式碼 - DATA = '../datasets/ecommerce/products.csv' - qty_stock = np.genfromtxt(DATA, delimiter=',', skip_header=1, usecols=4) - result = np.argsort(qty_stock) - top3_stock = result[::-1][:3] - return top3_stock + return np.argsort(stocks)[::-1][:3] def yellow_restock_cost(prices, stocks): @@ -70,19 +65,13 @@ def yellow_restock_cost(prices, stocks): 單價 < 500 的商品,每種各進貨 50 個,回傳總花費 (float/int) 提示:布林遮罩 + .sum() """ - # TODO: 你的程式碼 - DATA = '../datasets/ecommerce/products.csv' - unit_price = np.genfromtxt(DATA, delimiter=',', skip_header=1, usecols=3) - qty_stock = np.genfromtxt(DATA, delimiter=',', skip_header=1, usecols=4) - - lower_500 = unit_price[np.array(unit_price < 500)] - total_price = lower_500.sum()* 50 - return total_price + return (prices[prices < 500] * 50).sum() # ============================================================ # 🔴 挑戰題(25 分) # ============================================================ + def red_double11_prices(prices, stocks): """ 雙 11 定價規則(必須向量化,不能用 for-loop): @@ -92,18 +81,5 @@ def red_double11_prices(prices, stocks): 回傳每個商品的雙 11 售價 (ndarray) 提示:np.where 可以巢狀使用 """ - # TODO: 你的程式碼 - DATA = '../datasets/ecommerce/products.csv' - price = np.genfromtxt(DATA, delimiter=',', skip_header=1, usecols=3) - stock = np.genfromtxt(DATA, delimiter=',', skip_header=1, usecols=4) - - final_price = np.where( - stock >= 100, - price * 0.7, - np.where( - stock >= 20, - price * 0.9, - price - ) -) - return final_price + return np.where(stocks >= 100, prices * 0.7, + np.where((stocks >= 20) & (stocks <= 99), prices * 0.9, prices))