promptdojo_

The ML package map — numpy, pandas, sklearn, torch — step 1 of 7

The four packages at the top of every AI script

Open any machine-learning file Cursor generates and the first four lines are some subset of:

import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression
import torch

This chapter is the ML track's dataframes chapter, and it opens here on purpose: before the dataframes, know what each package is for. You don't need to use these libraries yet. You need the map — what each one is for — because the import block is the fastest way to read an AI-written script. Before you've seen a single function, the imports tell you what kind of program this is.

The map

  • numpy — arrays and fast math. Millions of numbers in a grid, operated on all at once. Everything else in this list is built on top of it.
  • pandas — tables. Rows and named columns, like a spreadsheet in code. Loading CSVs, filtering rows, grouping — that's pandas.
  • sklearn (installed as scikit-learn) — classic machine learning. Regression, clustering, train/test splits. The famous two-step: model.fit(X, y) then model.predict(X_new).
  • torch (PyTorch) — deep learning. Neural networks, tensors, GPUs. If the script mentions nn.Module or .backward(), you're in torch land.

And the conventions are rigid: numpy is always aliased to np, pandas to pd. torch is imported bare. sklearn is almost never imported whole — you pull specific classes from its submodules, like from sklearn.model_selection import train_test_split. An import block that breaks these conventions is a mild smell; one that imports torch to filter a spreadsheet is a loud one.

What an import actually binds

Here's the part that makes the whole block readable: a module is just an object with attributes. import numpy as np does two things — load the numpy module once, then bind it to the local name np. After that, np.array is ordinary attribute access, no different from config.timeout on any object you built yourself.

The editor on the right proves it with zero packages installed:

from types import SimpleNamespace

np = SimpleNamespace(__name__="numpy", array=lambda data: list(data))

print(np.__name__)
print(np.array([1, 2, 3]))

That's a fake np — a plain object wearing numpy's name, with one attribute called array. And np.array([1, 2, 3]) works, because "module" was never magic: it's a namespace, a bag of names you reach into with a dot. The real numpy is the same shape with about three thousand more attributes and twenty years of speed work.

(This editor runs Python's standard library only — you can't pip install numpy here, and you don't need to. The import mechanics are identical for every package you'll ever install.)

Where AI specifically gets this wrong

Three things to check in any AI-generated import block:

  1. Imports the whole zoo for a one-animal job. A script that filters a CSV needs pandas. Cursor will sometimes ship it with numpy, sklearn, and torch on top — leftovers from its training data. Unused imports don't crash, which is exactly why they accumulate.
  2. import sklearn then sklearn.linear_model.X. Importing a package does not automatically import its submodules. This one raises AttributeError at runtime. The fix is the convention: from sklearn.linear_model import LogisticRegression.
  3. Nonstandard aliases. import pandas as p runs fine and reads wrong to every Python programmer alive. If the alias isn't np, pd, or plt, ask what it's buying.

Run the editor. Two lines of output from a numpy that doesn't exist.