Back to all skills
kaggle-notebook-formatSKILL.md ↗

Use this skill when creating Python scripts that target Kaggle Notebooks. This skill ensures correct cell separator format (# %% [code] and # %% [markdown]), proper markdown cell formatting (each line prefixed with #, no triple quotes), and Kaggle-specific conventions (Chinese comments, English output, %pip install). Also covers common pitfalls: OpenCV video decoding limits and Chinese text rendering with PIL.

Kaggle Notebook Format Rules

Cell Separators

  • Code cells: # %% [code]
  • Markdown cells: # %% [markdown]

Markdown Cell Formatting

CRITICAL RULES:

  1. Every line must start with # (hash + space)
  2. NEVER use triple quotes (""" or ''') for markdown cells
  3. NO empty lines with only # - they create extra whitespace in rendered notebook

Correct markdown cell:

# %% [markdown]
# # Title
# Content line 1
# Content line 2
# - Bullet point 1
# - Bullet point 2

Code Cell Conventions

  • Printed output in English
  • File extension: .py (not .ipynb)
  • Dataset paths: /kaggle/input/dataset-name/
  • NEVER truncate print output — 必须原样完整输出数据,禁止用 text[:100]... 截断

Package Installation

  • Only install packages NOT pre-installed on Kaggle
  • Use %pip install -q package-name (not !pip install)
  • Common libraries (pandas, numpy, scipy, scikit-learn, torch, torchvision) are already available

Common Mistakes to Avoid

  1. Triple quotes in markdown cells → Use # prefix on every line
  2. Empty # lines → Remove them
  3. Missing # prefix → Every line must start with #
  4. Using ## Title → Use # Title only
  5. Using !pip → Use %pip

process video(always use ffmpeg)

example:

from IPython.display import Image, Video
import os
output_video_path='/kaggle/working/runs/detect/predict/650-1-y1_particle_video.avi'
# Using ffmpeg to compress the video to display
compressed_output_path = 'compressed_output_particle.mp4'
os.system(f'ffmpeg -i {output_video_path} -vcodec libx264 -crf 28 {compressed_output_path}')
display(Video(compressed_output_path, embed=True))

Common Pitfalls on Kaggle (实战踩坑记录)

1. 视频解码:OpenCV 读不了某些编码格式

问题: cv2.VideoCapture 在 Kaggle 上对 H.265/HEVC 等编码格式支持很差,cap.read() 返回 (False, None)

解决方案: 用 ffmpeg 解码为 raw BGR24 格式,再用 numpy 逐帧读取:

raw_video_path = "/kaggle/working/video_raw.rgb"
subprocess.run([
    "ffmpeg", "-y", "-i", VIDEO_PATH,
    "-f", "rawvideo", "-pix_fmt", "bgr24",
    "-v", "quiet", raw_video_path
], capture_output=True)

frame_bytes = width * height * 3
actual_frames = os.path.getsize(raw_video_path) // frame_bytes

with open(raw_video_path, "rb") as f:
    for frame_idx in range(actual_frames):
        raw_data = f.read(frame_bytes)
        frame = np.frombuffer(raw_data, dtype=np.uint8).reshape((height, width, 3))

获取视频元信息用 ffprobe 而非 cv2:

probe = subprocess.run(
    ["ffprobe", "-v", "quiet", "-print_format", "json",
     "-show_streams", "-select_streams", "v:0", VIDEO_PATH],
    capture_output=True, text=True
)
probe_data = json.loads(probe.stdout)
vstream = probe_data["streams"][0]
width = int(vstream["width"])
height = int(vstream["height"])
fps_num, fps_den = map(int, vstream["r_frame_rate"].split("/"))
fps = fps_num / fps_den

2. OpenCV putText 不支持中文

问题: cv2.putText() 只支持 ASCII 字符,中文会显示为乱码或方块。

解决方案: 使用 PIL 绘制中文文字:

from PIL import Image, ImageDraw, ImageFont

# 字体加载(使用wget从网络下载)
font_url = "https://github.com/adobe-fonts/source-han-sans/raw/release/OTF/SimplifiedChinese/SourceHanSansSC-Regular.otf"
font_path = "/kaggle/working/fonts/SourceHanSansSC-Regular.otf"
subprocess.run(["wget", "-q", "-O", font_path, font_url], capture_output=True)
pil_font = ImageFont.truetype(font_path, font_size)

def put_text_pil(frame_bgr, text, font_color, stroke_color, stroke_width):
    img_pil = Image.fromarray(cv2.cvtColor(frame_bgr, cv2.COLOR_BGR2RGB))
    draw = ImageDraw.Draw(img_pil)
    # 计算位置、绘制描边+正文...
    draw.text((text_x, text_y), text, fill=font_color, font=pil_font)
    return cv2.cvtColor(np.array(img_pil), cv2.COLOR_RGB2BGR)

3. ffmpeg 切片:scale 参数 -1 vs -2

问题: scale=640:-1 按比例缩放时,若计算出来的高度为奇数(如 1137),H.264 编码器报错退出,输出 0 字节文件:

height not divisible by 2 (640x1137)

解决: 改用 -2,让 ffmpeg 自动向下取最近的偶数:

VIDEO_SCALE = "640:-2"  # -2 保证高度为偶数(H.264 要求宽高均为偶数)