{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[],"dockerImageVersionId":28755,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"from pathlib import Path\nimport pandas as pd\nimport shutil\nimport csv","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-11T15:39:40.397035Z","iopub.execute_input":"2026-09-11T15:39:40.397319Z","iopub.status.idle":"2026-09-11T15:39:41.383704Z","shell.execute_reply.started":"2026-09-11T15:39:40.397285Z","shell.execute_reply":"2026-09-11T15:39:41.382571Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Sửa đường dẫn này nếu tên mount trên notebook khác.\nINDEX_DIR = Path(\"/kaggle/input/notebooks/phanbtho/index-img-net\")\n\nSHARD_INDEX = INDEX_DIR / \"shard_index.csv\"\nIMAGE_INDEX = INDEX_DIR / \"image_index.csv\"\nOUTPUT_FILE = Path(\"/kaggle/working/image_index.csv\")\n\n# 1. Tạo ánh xạ WNID -> shard_id từ shard_index.csv.\nwnid_to_shard = {}\n\nwith SHARD_INDEX.open(\"r\", newline=\"\", encoding=\"utf-8\") as f:\n    for row in csv.DictReader(f):\n        shard_id = int(row[\"id\"])\n\n        for wnid in row[\"folders\"].split(\"|\"):\n            wnid = wnid.strip()\n            if not wnid:\n                continue\n\n            if wnid in wnid_to_shard:\n                raise ValueError(\n                    f\"{wnid} xuất hiện ở cả shard \"\n                    f\"{wnid_to_shard[wnid]} và shard {shard_id}\"\n                )\n\n            wnid_to_shard[wnid] = shard_id\n\nprint(f\"Đã đọc {len(wnid_to_shard)} class từ shard_index.csv\")\n\nif len(wnid_to_shard) != 1000:\n    raise ValueError(\n        f\"shard_index.csv có {len(wnid_to_shard)} class, kỳ vọng 1000\"\n    )\n\n# 2. Đọc image_index.csv, thay shard_id và ghi sang file mới.\ntotal_rows = 0\nchanged_rows = 0\nmissing_wnids = set()\n\nwith IMAGE_INDEX.open(\"r\", newline=\"\", encoding=\"utf-8\") as src:\n    reader = csv.DictReader(src)\n\n    if \"wnid\" not in reader.fieldnames or \"shard_id\" not in reader.fieldnames:\n        raise ValueError(\n            f\"Thiếu cột wnid hoặc shard_id. Các cột hiện có: {reader.fieldnames}\"\n        )\n\n    with OUTPUT_FILE.open(\"w\", newline=\"\", encoding=\"utf-8\") as dst:\n        writer = csv.DictWriter(dst, fieldnames=reader.fieldnames)\n        writer.writeheader()\n\n        for row in reader:\n            total_rows += 1\n            wnid = row[\"wnid\"].strip()\n\n            if wnid not in wnid_to_shard:\n                missing_wnids.add(wnid)\n                continue\n\n            correct_shard = str(wnid_to_shard[wnid])\n\n            if row[\"shard_id\"].strip() != correct_shard:\n                changed_rows += 1\n                row[\"shard_id\"] = correct_shard\n\n            writer.writerow(row)\n\nif missing_wnids:\n    OUTPUT_FILE.unlink(missing_ok=True)\n    raise ValueError(\n        \"Các class trong image_index.csv không có trong shard_index.csv: \"\n        + \", \".join(sorted(missing_wnids))\n    )\n\nprint(f\"Tổng số ảnh: {total_rows:,}\")\nprint(f\"Số dòng được sửa shard_id: {changed_rows:,}\")\nprint(f\"Đã lưu: {OUTPUT_FILE}\")\nprint(f\"Kích thước: {OUTPUT_FILE.stat().st_size / 1e6:.1f} MB\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-11T15:40:40.802324Z","iopub.execute_input":"2026-09-11T15:40:40.802703Z","iopub.status.idle":"2026-09-11T15:40:59.680022Z","shell.execute_reply.started":"2026-09-11T15:40:40.802672Z","shell.execute_reply":"2026-09-11T15:40:59.679255Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"target = \"n02115641\"\nfound_shards = set()\n\nwith open(\"/kaggle/working/image_index.csv\", newline=\"\", encoding=\"utf-8\") as f:\n    for row in csv.DictReader(f):\n        if row[\"wnid\"] == target:\n            found_shards.add(row[\"shard_id\"])\n\nprint(target, \"correct shard:\", wnid_to_shard[target])\nprint(target, \"shards in corrected image_index:\", found_shards)\n\nassert found_shards == {str(wnid_to_shard[target])}","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-11T15:41:00.94239Z","iopub.execute_input":"2026-09-11T15:41:00.942704Z","iopub.status.idle":"2026-09-11T15:41:07.442331Z","shell.execute_reply.started":"2026-09-11T15:41:00.942678Z","shell.execute_reply":"2026-09-11T15:41:07.441455Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"shutil.copy2(\n    \"/kaggle/input/notebooks/phanbtho/index-img-net/class_index.csv\",\n    \"/kaggle/working/class_index.csv\"\n)\n\nshutil.copy2(\n    \"/kaggle/input/notebooks/phanbtho/index-img-net/shard_index.csv\",\n    \"/kaggle/working/shard_index.csv\"\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-09-11T15:42:02.052995Z","iopub.execute_input":"2026-09-11T15:42:02.053308Z","iopub.status.idle":"2026-09-11T15:42:02.075312Z","shell.execute_reply.started":"2026-09-11T15:42:02.053281Z","shell.execute_reply":"2026-09-11T15:42:02.074609Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}