PD-01-010-P · Primer — Transforming Columns
The idea in one sentence
A pandas column is a whole array of values at once, so instead of looping over rows to fix them one at a time, you write a single expression — df['price'] * 0.9 or df['name'].str.upper() — that transforms every value in the column together, and then you assign that result back onto the same column to rewrite it in place.
Why it exists
Raw data almost never arrives in the shape you need. Prices come in dollars when you want them after a discount; names come with stray spaces and mixed capitalization; a column called amt needs to become the readable amount. The naive instinct — borrowed from ordinary Python — is to write a for loop that walks down the rows and patches each cell. On a real table of a hundred thousand rows that is both painfully slow and painfully verbose.
Pandas exists to make that whole loop disappear. A column (a Series) behaves like one big value: multiply it and every number is multiplied; call a string method through .str and every string is cleaned. This is called vectorization, and it means a column transform is one short, readable line instead of a loop. Transforming columns is the daily bread of data work — you will spend more time reshaping existing columns than almost anything else — so pandas makes the common cases (arithmetic on numbers, cleanup on text, giving a column a better name) fast to write and fast to run.
How it works
The pattern has three moves you will use constantly. First, numeric ops: df['price'] * 0.9 produces a brand-new Series where every value is scaled — the operation broadcasts across the whole column at once. Second, string methods via the .str accessor: df['product'].str.strip() trims whitespace from every value, and calls chain, so .str.strip().str.upper() cleans and uppercases in one go. Third, to actually change the table you perform an in-place transform — you assign the result back with df['col'] = ..., overwriting the old column with the new values. Finally, renaming a column is a separate concern handled by df.rename(columns={'old': 'new'}), which changes the label without touching the data. Here is all four in one runnable example:
import pandas as pd
df = pd.DataFrame({
'product': [' Laptop ', 'phone', 'Tablet '],
'price': [1000, 500, 300],
})
# Numeric op: apply a 10% price cut, written back in place
df['price'] = df['price'] * 0.9
# String op: strip spaces and uppercase, written back in place
df['product'] = df['product'].str.strip().str.upper()
# Rename a column to something clearer
df = df.rename(columns={'price': 'sale_price'})
print(df)
# product sale_price
# 0 LAPTOP 900.0
# 1 PHONE 450.0
# 2 TABLET 270.0
Each column was rewritten by one expression, no loop in sight, and price came out both discounted and renamed.
The one gotcha
A transform that isn't assigned back does nothing to your DataFrame — pandas methods return a new result and leave the original untouched. Beginners write df['product'].str.strip() on its own line, see the cleaned values print, and assume the column is fixed — but it isn't, because .str.strip() handed back a fresh Series that was never stored anywhere. The very next time you use df['product'] the spaces are still there. The fix is the assignment: df['product'] = df['product'].str.strip(). The same trap bites with rename — by default it returns a renamed copy, so df.rename(columns={'amt': 'amount'}) alone changes nothing; you must write df = df.rename(...) (or pass inplace=True). The rule to burn in: if you want the change to stick, capture the result — either back onto the column with df['col'] = or back onto the whole frame with df =.
See it — one expression rewrites a whole column
flowchart TD
A["Column: price<br/>[1000, 500, 300]"] --> B["Vectorized op<br/>Series * 0.9"]
B --> C["New Series<br/>[900, 450, 270]"]
C --> D{"Assign back?<br/>df['price'] = ..."}
D -->|"Yes"| E["Column rewritten<br/>change sticks"]
D -->|"No"| F["Result discarded<br/>column unchanged"]
The one-line takeaway
Transform a whole column with one vectorized expression — arithmetic for numbers, .str methods for text — and always assign the result back with df['col'] = ... (or df = df.rename(...)) so the change actually sticks.
Where you'll meet it
You'll meet column transforms in the first five minutes of every cleaning job: stripping and lowercasing messy text so joins line up, converting prices or units with a bit of arithmetic, and renaming cryptic source columns like cust_id into names your teammates can read. You'll meet the gotcha the first time a "cleaned" column stubbornly keeps its trailing spaces because you forgot the assignment — a bug so common it's practically a rite of passage. Interviewers probe it directly: "how would you uppercase every name in this column without a loop?", "why didn't this rename change anything?", and "what does .str do?" Once the assign-it-back reflex is automatic, you can reshape any column in a single confident line — and that fluency is the foundation everything else in pandas is built on.
Named concepts: in-place transform, string methods (.str), numeric ops, renaming
