Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 19 additions & 14 deletions homework/m1_numpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,62 +11,67 @@
"""
import numpy as np


# ============================================================
# 🟢 送分題(每題 10 分,共 30 分)
# ============================================================

def green_mean():
"""建立 [10, 20, 30, 40, 50],回傳所有元素的平均值 (float)"""
# TODO: 你的程式碼
pass
arr = np.array([10, 20, 30, 40, 50])
return arr.mean()


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 分)
# 以下函式會接收從 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: 你的程式碼
pass
return prices[prices>1000].size


def yellow_top3_stock_indices(stocks):
"""
回傳庫存最多的前 3 個商品的索引位置 (ndarray, 由大到小排)
提示:np.argsort
"""
# TODO: 你的程式碼
pass
return np.argsort(stocks)[::-1][:3]


def yellow_restock_cost(prices, stocks):
"""
單價 < 500 的商品,每種各進貨 50 個,回傳總花費 (float/int)
提示:布林遮罩 + .sum()
"""
# TODO: 你的程式碼
pass

return (prices[prices < 500] * 50).sum()

# ============================================================
# 🔴 挑戰題(25 分)
# ============================================================


def red_double11_prices(prices, stocks):
"""
雙 11 定價規則(必須向量化,不能用 for-loop):
Expand All @@ -76,5 +81,5 @@ def red_double11_prices(prices, stocks):
回傳每個商品的雙 11 售價 (ndarray)
提示:np.where 可以巢狀使用
"""
# TODO: 你的程式碼
pass
return np.where(stocks >= 100, prices * 0.7,
np.where((stocks >= 20) & (stocks <= 99), prices * 0.9, prices))
49 changes: 41 additions & 8 deletions homework/m2_pandas_cleaning.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -29,7 +31,8 @@ def green_shape(df):
提示:df.shape
"""
# TODO: 你的程式碼
pass
return df.shape



def green_dtypes(df):
Expand All @@ -38,7 +41,7 @@ def green_dtypes(df):
提示:df.dtypes
"""
# TODO: 你的程式碼
pass
return df.dtypes


# ============================================================
Expand All @@ -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):
Expand All @@ -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):
Expand All @@ -72,7 +85,8 @@ def yellow_drop_duplicates(df):
提示:df.drop_duplicates()
"""
# TODO: 你的程式碼
pass
df_drop = df.drop_duplicates()
return df_drop


# ============================================================
Expand All @@ -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

39 changes: 31 additions & 8 deletions homework/m3_pandas_advanced.py
Original file line number Diff line number Diff line change
Expand Up @@ -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():
"""
Expand All @@ -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


# ============================================================
Expand All @@ -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):
Expand All @@ -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):
Expand All @@ -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


# ============================================================
Expand All @@ -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
42 changes: 35 additions & 7 deletions homework/m4_timeseries.py
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand All @@ -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():
Expand All @@ -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)


# ============================================================
Expand All @@ -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):
Expand All @@ -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):
Expand All @@ -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


# ============================================================
Expand All @@ -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
Loading
Loading