Loading and Filtering Data With pandas
A pandas DataFrame is a table of named columns and labeled rows, similar to an Excel spreadsheet, created with pd.DataFrame from a dictionary.
Why a Table Needs Its Own Structure
A spreadsheet holds information in rows and columns, and you can sort and filter it by hand. pandas is a Python library for data wrangling and analysis, and it brings a comparable table into code. The central structure in pandas is the DataFrame. In plain terms, a DataFrame is a table, similar to an Excel spreadsheet, and pandas provides methods for modifying and operating on that table.
This article follows one small working example. You will build a table from a dictionary, trace how that table is organized, see why its columns can hold different kinds of data, and then filter it with a condition. Along the way you will follow the steps of a query so that you can explain its output, and you will learn where an unexpected result is most likely to come from.
Building a Table From a Dictionary
Each key in the dictionary is a column name, and each key points to a list of values, one value per person or record. The last line passes that dictionary to pd.DataFrame, which builds the table. The example below uses a small generated table with the same shape as the source's four-person example: three columns named Name, Location, and Age, and four rows.
Name Location Age
0 Ana Lisbon 25
1 Ben Oslo 28
2 Peter Denver 34
3 Linda Austin 41- The dictionary keys Name, Location, and Age become the column headers.
- Each list supplies the cell values for its column, in order from top to bottom.
pd.DataFrame(people)builds the table; the final line displays it.
Trace the construction step by step. The dictionary keys became the three column names. The first item in each list lands in the first row, the second item in the second row, and so on. Row labels 0 through 3 were not written in the dictionary at all; they are assigned to the rows and appear at the left edge of the table. Because each list is read position by position, the values in a row line up across columns, so every row describes one person.
Reading Columns, Rows, and Labels
A DataFrame has columns, and each column has a name. Each column holds a sequence of values, and the rows line up across the columns. The row labels on the left identify each row. A row is therefore one person's record, spread across all the columns. When you read the table, you read it in two directions at once: down a column to see every value of one attribute, and across a row to see every attribute of one record.
A pandas DataFrame is a table of named columns and labeled rows, similar to an Excel spreadsheet, created with pd.DataFrame from a dictionary.
Column Types in a DataFrame Versus a NumPy Array
The source contrasts pandas with NumPy. NumPy requires that all entries in an array be of the same type. pandas relaxes that rule by allowing each column to have a separate type. A column can hold integers, dates, floating-point numbers, or strings. In the table built above, the Age column holds whole numbers, while Name and Location hold text. This is the feature that distinguishes a DataFrame from a grid where every entry must match.
Use the picture of a spreadsheet as a starting point. In a spreadsheet, each column can contain numbers or text, and the program keeps track of that. A NumPy array is closer to a grid where every cell must match the others, while a DataFrame keeps each column as its own typed sequence inside one labeled table. The consequence matters later: when a column's type is different from what you expect, a condition on that column will compare values of that type.
Filtering Rows With a Condition
pandas makes it possible to query a table with conditions. Here is a query on the same DataFrame. It asks for every row whose Age is greater than 30. Before you read the result, make a prediction about which rows the query will return.
What do you think happens?
Which rows does data_pandas[data_pandas.Age > 30] return?
Reveal answer
Only Peter and Linda, keeping labels 2 and 3
Ages 34 and 41 are greater than 30, and those are the rows for Peter (label 2) and Linda (label 3). Ana and Ben, with ages 25 and 28, do not satisfy the condition.
Name Location Age
2 Peter Denver 34
3 Linda Austin 41data_pandas.Age > 30 produces one True or False answer for each row.- The outer brackets keep only the rows that answered True.
- The result keeps the original row labels 2 and 3.
Tracing the age-above-30 query
Starting from the four-row table with labels 0 to 3, determine which rows data_pandas[data_pandas.Age > 30] returns and which labels they keep.
- 1Stage 1: evaluate the condition
The expression
data_pandas.Age > 30 is checked against each row's Age value. Row 0 has 25, which is not greater than 30, so the answer is False. Row 1 has 28, also False. Row 2 has 34, which is True. Row 3 has 41, which is True. - 2Stage 2: keep the True rows
The rows that answered True are kept. Rows 0 and 1 are dropped. Rows 2 and 3 survive.
- 3Stage 3: preserve the labels
The surviving rows keep the labels 2 and 3 they had in the original table. The values in each row are unchanged; only the rows were selected.
The result contains two rows: Peter with label 2 and Linda with label 3.
The query reads in two stages. First, the expression is checked against every row's Age, producing a yes or no answer per row. Second, the rows that answered yes are kept in the result. Because the query is a filter, its output is a subset of the original table, and the source shows the filtered table keeping the original row labels. That detail is the one to watch when you trace results.
Mistakes That Produce Unexpected Results
When a result differs from what you expected, the source recommends a fixed order of checks: look at the table first, then the condition, then the output. The goal is to find the stage where the divergence begins, rather than changing the code at random. The mistakes below are the most common places where that divergence starts.
Common mistake Assuming the output row numbers are positions in the filtered table
What it looks likeAfter the age query, the rows are labeled 2 and 3, not 0 and 1.
Why it failsA filter keeps the original index labels, so the label of a surviving row can differ from its position in the new, smaller result.
Do this insteadRead the label shown at the left edge as the row's identity in the original table, and do not assume it counts from zero after filtering.
Common mistake Expecting a numeric comparison from a column that holds text
What it looks likeA column of ages that was loaded as text would be compared as text, not as numbers, so a check against 30 may not behave as the number comparison you intended.
Why it failsA condition compares values using the column's type, so the type of the column determines what the condition actually compares.
Do this insteadCheck the table first to see what each column holds, then confirm the condition is comparing values of the type you intend.
Common mistake Treating a row's label as proof of which values it contains
What it looks likeLabel 2 is Peter in the original table; the label alone does not tell you his age without reading the Age column in that row.
Why it failsLabels identify rows, but the values in the row are what the condition examines.
Do this insteadRead across the row to confirm the values that the condition used.
Practicing a Filter Trace
Using the four-row table from this article (Ana 25, Ben 28, Peter 34, Linda 41), predict the result of data_pandas[data_pandas.Age < 30]. State which rows are returned and which labels they keep. Then explain which stage of the query each answer depends on.
Hints
- Evaluate the condition Age < 30 for each row before deciding which rows to keep.
- Remember that the surviving rows keep their original labels.
- Compare your answer with the condition-then-output order of checks.
Key Takeaways
- A pandas
DataFrameis a table of named columns and labeled rows, created withpd.DataFramefrom a dictionary whose keys become column names. - Unlike a NumPy array, which requires one type for all entries, a
DataFramelets each column have its own type, such as integers or strings. - A condition like
data_pandas[data_pandas.Age > 30] first produces a True or False answer for each row, then keeps only the True rows along with their original index labels. - When a result differs from expectation, check the table, then the condition, then the output to find the stage where the divergence begins.