@@ -158,154 +158,6 @@ project/
158158
159159---
160160
161- ## ⭐ 0) 前提
162-
163- - 環境: ** Python 3.10.15 / pandas 2.2.2**
164- - 指定シグネチャ厳守
165- - IO禁止、print禁止、不要sort禁止
166-
167- ---
168-
169- ## ⭐ 1) 問題
170-
171- - ** 2019-08-16 時点での全製品の価格を求める**
172- - 初期価格は全製品 10
173- - Products には価格変更履歴が記録
174-
175- - 入力 DF: ` products ` (product_id, new_price, change_date)
176- - 出力: ` product_id, price `
177-
178- ---
179-
180- ## ⭐ 2) 実装(指定シグネチャ厳守)
181-
182- ### 🎯 Pandas最適処理順
183-
184- 対象日フィルタ
185- ↓
186- groupby + idxmax で最新抽出
187- ↓
188- 全製品リスト生成
189- ↓
190- map結合 + fillna(10)
191-
192- ### 💎 最適実装
193-
194- ``` python
195- import pandas as pd
196-
197- def price_at_given_date (products : pd.DataFrame) -> pd.DataFrame:
198-
199- # --- 対象日以前のデータのみ抽出
200- target_date = ' 2019-08-16'
201- before_target = products[products[' change_date' ] <= target_date]
202-
203- # --- 各製品の最新価格を取得(groupby + idxmax)
204- if not before_target.empty:
205- latest_idx = before_target.groupby(' product_id' )[' change_date' ].idxmax()
206- latest_prices = before_target.loc[latest_idx, [' product_id' , ' new_price' ]]
207- else :
208- latest_prices = pd.DataFrame(columns = [' product_id' , ' new_price' ])
209-
210- # --- 全製品リストを生成
211- all_products = products[[' product_id' ]].drop_duplicates()
212-
213- # --- 軽量結合(map優先)
214- price_mapper = latest_prices.set_index(' product_id' )[' new_price' ]
215-
216- out = pd.DataFrame({
217- ' product_id' : all_products[' product_id' ],
218- ' price' : all_products[' product_id' ].map(price_mapper).fillna(10 ).astype(int )
219- })
220-
221- return out
222- ```
223-
224- ---
225-
226- ## ⭐ 3) アルゴリズム説明
227-
228- ### 使用API
229-
230- - ** ` groupby('product_id')['change_date'].idxmax() ` ** : 各製品の最新日付の行インデックスを取得
231- - ** ` map() ` ** : 単一キー結合の最速手段
232- - ** ` fillna(10) ` ** : デフォルト値設定
233-
234- ### 処理フロー
235-
236- 1 . ** 日付フィルタ** : ` change_date <= '2019-08-16' `
237- 2 . ** 最新抽出** : ` idxmax() ` で各製品の最新変更日
238- 3 . ** 全製品** : ユニークリスト作成
239- 4 . ** 結合** : ` map() ` で高速マッピング
240-
241- ---
242-
243- ## ⭐ 4) 計算量
244-
245- | 処理 | 計算量 | 備考 |
246- | ---------------- | -------- | ------------------ |
247- | フィルタ | ** O(N)** | ブール索引 |
248- | groupby + idxmax | ** O(N)** | ハッシュテーブル |
249- | map | ** O(M)** | M = ユニーク製品数 |
250- | ** 合計** | ** O(N)** | N = 全レコード数 |
251-
252- ---
253-
254- ## ⭐ 5) 図解
255-
256- ### 📊 処理フロー図
257-
258- ``` mermaid
259- flowchart TD
260- A[Products DataFrame]
261- B[Filter: change_date <= 2019-08-16]
262- C[GroupBy product_id + idxmax]
263- D[Extract latest prices]
264- E[Get all unique products]
265- F[Map prices]
266- G[Fill missing with 10]
267- H[Output: product_id, price]
268-
269- A --> B
270- B --> C
271- C --> D
272- A --> E
273- D --> F
274- E --> F
275- F --> G
276- G --> H
277- ```
278-
279- ---
280-
281- ## 📝 実行例
282-
283- ``` python
284- # テストデータ
285- products = pd.DataFrame({
286- ' product_id' : [1 , 2 , 1 , 1 , 2 , 3 ],
287- ' new_price' : [20 , 50 , 30 , 35 , 65 , 20 ],
288- ' change_date' : pd.to_datetime([
289- ' 2019-08-14' , ' 2019-08-14' , ' 2019-08-15' ,
290- ' 2019-08-16' , ' 2019-08-17' , ' 2019-08-18'
291- ])
292- })
293-
294- result = price_at_given_date(products)
295- print (result)
296- ```
297-
298- ** 出力** :
299-
300- ```
301- product_id price
302- 0 1 35
303- 1 2 50
304- 2 3 10
305- ```
306-
307- ---
308-
309161## 🖥️ VSCodeでの使い方
310162
311163### 1️⃣ ファイル保存
0 commit comments