Skillversitas

Loading Data

Every model is only as good as the data that reaches it, and the data has to get in first. pandas is the standard loader for tabular data - CSV, Excel, Parquet, JSON, and database tables all come in as a DataFrame, the table-like structure the rest of the tutorial operates on. This chapter covers the common sources and the loading options that prevent the classic first-day problems: wrong types, mystery columns, and memory blowups.

CSV Files

import pandas as pd

df = pd.read_csv("sales.csv")
print(df.shape)        # (rows, columns)
print(df.head())       # first five rows
print(df.dtypes)       # the inferred type of every column

Always run head and dtypes immediately after loading - half of all "weird model behavior" starts with a column that pandas guessed wrong (a number read as text, a date read as an integer). The options that matter most:

df = pd.read_csv(
    "sales.csv",
    sep=";",                     # not every CSV uses commas
    na_values=["N/A", "none", ""],   # treat these as missing
    parse_dates=["created_at"],      # parse to datetime at load time
    usecols=["order_id", "amount", "created_at"],   # skip the rest
    dtype={"customer_id": str},     # force a type (e.g. leading zeros)
)

Other Common Formats

df_excel = pd.read_excel("report.xlsx", sheet_name="Q3")
df_parquet = pd.read_parquet("events.parquet")     # fast, typed, compressed
df_json = pd.read_json("records.json")
df_sql = pd.read_sql("SELECT * FROM orders", con=engine)   # via SQLAlchemy

Parquet is the best default for anything larger than a few hundred MB: columnar, typed, compressed, and far faster than CSV for repeated loading. Excel is for hand-made reports (and its sheet names matter). SQL reads pull straight from a database, which is how production pipelines usually start.

Small and Synthetic Data

from sklearn.datasets import fetch_california_housing, load_iris

iris = load_iris(as_frame=True)     # a classic 150-row labeled dataset
X = iris.frame[["sepal length (cm)", "sepal width (cm)",
                "petal length (cm)", "petal width (cm)"]]
y = iris.frame["target"]

housing = fetch_california_housing(as_frame=True)   # a larger real dataset

The scikit-learn dataset loaders are the right tool for examples and unit tests: they need no files, no licenses to track, and no network in CI (they cache locally). When working on a real project, the "data" is your CSV or your database, and the loaders above are the front door.

Keeping an Eye on Memory

print(df.memory_usage(deep=True).sum() / 1e6, "MB")

# cut it: downcast numeric types and categorize strings
for col in df.select_dtypes("int64").columns:
    df[col] = pd.to_numeric(df[col], downcast="integer")
for col in df.select_dtypes("object").columns:
    if df[col].nunique() / len(df) < 0.5:
        df[col] = df[col].astype("category")

Large DataFrames usually want category dtype for low-cardinality string columns and downcasted integers - often a 3-5x memory reduction with no information loss. If the dataset does not fit in memory at all, the tool changes (dask, Polars, or SQL) and pandas is no longer the right loader.

Summary

Load with the format-appropriate pandas reader, inspect head and dtypes before anything else, and use the targeted options - na_values, parse_dates, usecols, dtype - to fix problems at the door. Prefer Parquet for large or repeated loads, scikit-learn loaders for examples and tests, and check memory_usage before the dataset decides to live on the swap partition.