agentleFS
ludo-technologiesludo-technologies/python-best-practices/skills/data-science/SKILL.md

data-science

Skill34 starsChanged 4 months agoMITView on GitHub

NumPy and pandas best practices for data science and ML code covering vectorization, DataFrame indexing and mutation under Copy-on-Write, dtypes, schema validation with pandera, reproducible randomness, transformation style, array typing, and numeric testing. Use when writing, reviewing, or refactoring code that uses numpy, pandas, DataFrames, ndarrays, Jupyter notebooks, or data pipelines, or when the user asks about pandas/numpy performance or idioms.

7 other projects use a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

3 rules. 0 are common, 3 are distinctive, and 0 are very specific to this project.

  • 0

    Common

    Most of the 5 edited versions we read keep these.

  • 3

    Distinctive

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Keep computation in compiled NumPy/pandas code instead of the Python interpreter.

    line 18
  2. Distinctive:

    Write to DataFrames in ways that are correct under Copy-on-Write and visible in the data flow.

    line 26
  3. Distinctive:

    Write DataFrame transformations that read top-to-bottom as a single pipeline.

    line 57

“Common” is measured: kept by at least 6 in 10 of the 5 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Python Data Science

NumPy and pandas best practices for data science and ML code. Designed for AI agents and LLMs to write fast, correct, and reproducible numeric code.

Numeric code has idioms that differ from general Python: loops are the anti-pattern, data structures are immutable buffers, and dtypes are a design decision. Where a rule here overlaps a coding-standards rule, this skill takes precedence for array and DataFrame code.

Categories

Vectorization [CRITICAL]

Keep computation in compiled NumPy/pandas code instead of the Python interpreter.

RuleDescription
vec-no-python-loopsVectorize instead of Python loops, iterrows, and row-wise apply (10-1000x faster)
vec-no-incremental-growthBuild arrays and DataFrames once, not incrementally (O(n) vs O(n²))

Indexing & Mutation [CRITICAL]

Write to DataFrames in ways that are correct under Copy-on-Write and visible in the data flow.

RuleDescription
mut-loc-not-chainedAssign with .loc, never with chained indexing
mut-no-inplaceAvoid inplace=True

Data Types [HIGH]

Make dtypes an explicit decision rather than an inference result.

RuleDescription
dtype-explicit-ioSpecify dtypes when loading data
dtype-categoricalUse category dtype for low-cardinality strings
dtype-numpy-explicitChoose NumPy dtypes explicitly

Schema Validation [HIGH]

Validate tabular data where it enters the system.

RuleDescription
schema-panderaValidate DataFrames at boundaries with pandera

Reproducibility [HIGH]

Make experiments repeatable and free of hidden global state.

RuleDescription
repro-default-rngUse an explicit Generator for randomness

Transformation Style [MEDIUM]

Write DataFrame transformations that read top-to-bottom as a single pipeline.

RuleDescription
style-method-chainingExpress transformations as method chains
style-named-aggregationUse named aggregation in groupby

Typing [MEDIUM]

Type hints that carry dtype and column information.

RuleDescription
type-array-annotationsAnnotate arrays and frames with precise types

Testing [MEDIUM]

Assertions that fit floating-point arrays and DataFrames.

RuleDescription
test-numeric-assertionsCompare numeric results with tolerance-aware assertions

Quick Reference

Vectorization

# Whole-array operations, not loops / iterrows / apply(axis=1)
df["total"] = df["price"] * df["qty"]
rate = np.select([df["qty"] >= 100, df["qty"] >= 10], [0.2, 0.1], default=0.0)

# Collect, then build once
records = [{"id": item.id, "score": score(item)} for item in items]
results = pd.DataFrame.from_records(records)
combined = pd.concat(frames, ignore_index=True)

Indexing & Mutation

# .loc in one step; chained assignment never reaches df under Copy-on-Write
df.loc[df["status"] == "pending", "priority"] = "high"

# Returning form, not inplace=True
df = df.dropna(subset=["email"]).sort_values("created_at")

Data Types

df = pd.read_csv(
    path,
    dtype={"customer_id": "Int64", "zip_code": "string", "region": "category"},
    parse_dates=["created_at"],
)
SEVERITY = pd.CategoricalDtype(["low", "medium", "high"], ordered=True)
embeddings = np.zeros((n, 768), dtype=np.float32)

Schema Validation

import pandera.pandas as pa
from pandera.typing import DataFrame, Series


class OrderSchema(pa.DataFrameModel):
    order_id: Series[int] = pa.Field(unique=True)
    price: Series[float] = pa.Field(ge=0)

    class Config:
        strict = True


def load_orders(path: str) -> DataFrame[OrderSchema]:
    return OrderSchema.validate(pd.read_csv(path))

Reproducibility

def run_experiment(seed: int) -> Result:
    rng = np.random.default_rng(seed)
    split_rng, noise_rng = rng.spawn(2)
    ...

def add_noise(x: np.ndarray, rng: np.random.Generator) -> np.ndarray:
    return x + rng.normal(scale=0.1, size=x.shape)

Transformation Style

monthly = (
    pd.read_csv("sales.csv", parse_dates=["date"])
    .assign(
        revenue=lambda d: d["price"] * d["qty"],
        month=lambda d: d["date"].dt.to_period("M"),
    )
    .loc[lambda d: d["revenue"] > 0]
    .groupby("month", as_index=False)
    .agg(total_revenue=("revenue", "sum"), orders=("order_id", "count"))
)

Typing

import numpy.typing as npt

def to_float32(values: npt.ArrayLike) -> npt.NDArray[np.float32]:
    return np.asarray(values, dtype=np.float32)

Testing

np.testing.assert_allclose(result, expected, rtol=1e-6, atol=1e-12)
pd.testing.assert_frame_equal(result_df, expected_df, check_like=True)

See Also

  • coding-standards - General Python rules; validation-pydantic, design-no-global-singleton, and doc-type-hints have direct counterparts here
  • testing - pytest structure, fixtures, and mocking that numeric tests still follow

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

Reviews can't be read right now.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.