Python for data cheat sheet
The tools of the course on one page, from a file to a report. Each part names the lesson that teaches it.
Read a text file
Lesson: Read a text file
with open("notes.txt", encoding="utf-8") as file:
text = file.read() # all the text
lines = text.splitlines() # a list of lines
with open("notes.txt", encoding="utf-8") as file:
for line in file: # one line at a time
print(line.strip())
for number, line in enumerate(lines, start=1):
print(number, line)
- Python closes the file when the block of
withends. - Write
encoding="utf-8"each time. strip()removes the spaces and the line end around a text.
Rows from a CSV file
Lesson: Rows from a CSV file
import csv
with open("pets.csv", newline="",
encoding="utf-8") as file:
rows = list(csv.reader(file))
header = rows[0] # ['name', 'age']
data = rows[1:] # each row is a list of text
position = header.index("age") # 1
ages = [int(row[position]) for row in data]
- Do not split the lines at the commas yourself. A value can have a comma in it.
- Write
newline=""in eachopencall for a CSV file. - Each value of a CSV file is text. Convert a number with
int("12")orfloat("3.5").
Rows as dictionaries
Lesson: Rows as dictionaries
import csv
def load_pets(file_name):
with open(file_name, newline="",
encoding="utf-8") as file:
rows = list(csv.DictReader(file))
for row in rows:
row["age"] = int(row["age"])
return rows
pets = load_pets("pets.csv")
print(len(pets)) # 2
print(pets[0]) # {'name': 'Biscuit', 'age': 4}
oldest = pets[0]
for pet in pets:
if pet["age"] > oldest["age"]:
oldest = pet
DictReaderuses the header row for the keys of each row.- Convert the numbers one time, after you read the file.
- Look at the number of rows and at the first row before you use the data.
Filter and pick
Lesson: Filter and pick
# Keep some rows
long_trips = [
trip for trip in trips if trip["minutes"] > 30
]
# Keep one value of each row
starts = [trip["start"] for trip in trips]
# Each value one time, in order
stations = sorted(set(starts))
| Code | Result |
|---|---|
len(values) |
the number of items |
sum(values) |
the total of the numbers |
min(values) |
the smallest value |
max(values) |
the largest value |
sum(values) / len(values) |
the average |
round(7.4567, 1) |
7.5 |
Sort and rank
Lesson: Sort and rank
sorted([34, 6, 20]) # [6, 20, 34]
sorted([34, 6, 20], reverse=True) # [34, 20, 6]
# Rows by one value. The largest is first.
longest_first = sorted(
trips,
key=lambda trip: trip["minutes"],
reverse=True,
)
top5 = longest_first[:5]
# The one row with the largest value
longest = max(
trips, key=lambda trip: trip["minutes"]
)
# By the rider, and then by the minutes
by_rider = sorted(
trips,
key=lambda t: (t["rider"], t["minutes"]),
)
A lambda is a function in one line. A minus sign in the key, such as -t["minutes"], puts the largest number first.
Count and group
Lesson: Count and group
from collections import Counter
starts = [trip["start"] for trip in trips]
counts = Counter(starts)
counts["Harbor Gate"] # the count of one value
counts.most_common(2) # the 2 largest counts
# A total for each group
minutes = {}
for trip in trips:
bike = trip["bike"]
total = minutes.get(bike, 0)
minutes[bike] = total + trip["minutes"]
# The rows of each group
groups = {}
for trip in trips:
rider = trip["rider"]
if rider not in groups:
groups[rider] = []
groups[rider].append(trip)
get(key, 0) gives 0 for a key that is not in the dictionary yet.
Numbers that describe data
Lesson: Numbers that describe data
import statistics
times = [10, 12, 14, 20, 600]
statistics.mean(times) # 131.2
statistics.median(times) # 14
min(times), max(times) # (10, 600)
- One strange value moves the mean. It does not move the median.
- Look at
minandmaxbefore you trust a mean. statistics.mean([])stops with an error. Check the length of the list first.
Clean messy data
Lesson: Clean messy data
| Code | Result |
|---|---|
" Old Mill ".strip() |
"Old Mill" |
"MEMBER".lower() |
"member" |
"old mill".title() |
"Old Mill" |
" old mill ".split() |
["old", "mill"] |
" ".join(["old", "mill"]) |
"old mill" |
def to_number(text):
try:
return int(text)
except ValueError:
return None # the text is not a number
# Keep the first row with each trip_id
seen = set()
unique = []
for row in rows:
if row["trip_id"] not in seen:
seen.add(row["trip_id"])
unique.append(row)
Do not change the source file. Count the rows that you remove, and report the count.
Dates and times
Lesson: Dates and times
from datetime import datetime
start = datetime.fromisoformat("2026-06-01T08:15")
start.year, start.month, start.day # (2026, 6, 1)
start.hour, start.minute # (8, 15)
start.weekday() # 0, which is Monday
start.strftime("%A") # 'Monday'
end = datetime.fromisoformat("2026-06-01T09:00")
(end - start).total_seconds() / 60 # 45.0
# A date in another form
datetime.strptime("01/06/2026", "%d/%m/%Y")
| Code | Meaning | Example |
|---|---|---|
%A |
the name of the weekday | Monday |
%d |
the day of the month | 01 |
%m |
the month as a number | 06 |
%B |
the name of the month | June |
%Y |
the year | 2026 |
%H:%M |
the hour and the minute | 08:15 |
Join two tables
Lesson: Join two tables
# A lookup dictionary: from a name to its zone
zone_of = {
station["name"]: station["zone"]
for station in stations
}
# Add the value to each row
for trip in trips:
start = trip["start"]
trip["zone"] = zone_of.get(start, "unknown")
# The stations that have no trip
used = set([trip["start"] for trip in trips])
no_trips = [
station["name"]
for station in stations
if station["name"] not in used
]
Check the two sides: the keys of the rows that have no match, and the keys of the second table that no row uses. Keep a row with no match under a clear label, and report it.
JSON data
Lesson: JSON data
| JSON | Python |
|---|---|
| an object in braces | a dictionary |
| a list in brackets | a list |
| text in double quotes | a string |
| a number | an int or a float |
true false |
True False |
null |
None |
import json
with open("station.json", encoding="utf-8") as file:
station = json.load(file) # from a file
print(station["hours"]["from"])
point = json.loads('{"x": 2, "y": 5}') # from text
text = json.dumps(point, indent=2) # to text
# A file with one JSON value on each line
events = []
with open("events.jsonl", encoding="utf-8") as file:
for line in file:
if line.strip() != "":
events.append(json.loads(line))
Words in text
Lesson: Words in text
from collections import Counter
def words(text):
result = []
for piece in text.lower().split():
word = piece.strip(".,!?;:")
if word != "":
result.append(word)
return result
counts = Counter()
for comment in comments:
counts.update(words(comment))
# A whole word, and not a piece of a word
"art" in words("The start was hard") # False
# Chunks of 2 items
for start in range(0, len(items), 2):
print(items[start:start + 2])
Leave out the stop words, such as the, a and is, before you look at the largest counts.
Write files
Lesson: Write files
| Mode | Meaning |
|---|---|
"r" |
read. This is the default. |
"w" |
write. Python empties a file that exists. |
"a" |
append. Python adds to the end of the file. |
with open("notes.txt", "w",
encoding="utf-8") as file:
file.write("First line\n")
with open("pets.csv", "w", newline="",
encoding="utf-8") as file:
writer = csv.DictWriter(
file, fieldnames=["name", "age"]
)
writer.writeheader()
writer.writerows(pets)
print(f"[{'Old Mill':<12}]") # [Old Mill ]
print(f"[{42:>6}]") # [ 42]
print(f"[{3.14159:>8.2f}]") # [ 3.14]
In an f-string, <12 puts a value to the left in 12 characters, >6 puts it to the right in 6 characters, and .2f gives 2 digits after the decimal point.