pandas brought the data frame to Python, an idea it borrowed from the R language.
A DataFrame is built from columns, and each column is stored as a Series.
Underneath, most columns are NumPy arrays, which is why column maths is fast.
The index labels the rows; by default it counts 0, 1, 2 and so on, but it can hold dates or IDs instead.
Selecting one column, as in sales["price"], returns a Series, while a list of columns returns a DataFrame.
Arithmetic between two Series lines values up by index label, not by position.
Where the labels of two Series do not match, the result is NaN, the pandas marker for a number that is not there.
The read_csv function is the usual way in, and it guesses each column's type from the file.
The head method shows the first rows, info shows column types and counts, and describe gives summary statistics.
A DataFrame lives in memory, so a file larger than the computer's memory will not load in one go.
Reading in chunks, loading only the columns you need, or using smaller types are the usual fixes.
Many operations return a new DataFrame rather than changing the old one, so the result must be assigned back.
Calling sales.dropna() on a line of its own, for example, leaves sales unchanged.
Most Python data and charting libraries accept DataFrames directly.
A common confusion is between the index and an ordinary column: the index labels the rows and is not a column itself.