GEOG 30323: Data Analysis & Visualization
2026-10-27
pd.read_csv()pd.read_table()','';''|''\t' in pandas)sep parameter in read_csv(); defaults to commapandas with the read_fwf() function; supply a list of column widths to the widths parameterread_excel() function in pandaspandas API comprises the functions, methods, etc. that you use in pandaswhere, outFields, resultRecordCount) are the request{
"attributes" : {
"Reported_Date" : "2026-10-25T13:12:00",
"Nature_Of_Call" : "THEFT",
"BLOCK_ADDRESS" : "10000 HARMON RD"
}
},
requests library sends the request and builds the URL for you.json() turns the response into Python dictionaries and listsimport pandas as pd
import requests
base = 'https://services5.arcgis.com/3ddLCBXe1bRt7mzj/arcgis/rest/services/'
endpoint = base + 'CFW_Open_Data_Police_Crime_Data_Table_view/FeatureServer/0/query'
params = {
'where': "Nature_Of_Call = 'THEFT' AND Reported_Date LIKE '2026%'",
'outFields': '*',
'f': 'json'
}
data = requests.get(endpoint, params = params).json()
data.keys()dict_keys(['objectIdFieldName', 'uniqueIdField', 'globalIdFieldName', 'fields', 'exceededTransferLimit', 'features'])
'features'; a list comprehension pulls them out Reported_Date Nature_Of_Call BLOCK_ADDRESS
0 2026-03-28T16:52:25 THEFT 6100 TILAPIA DR
1 2026-04-23T14:58:16 THEFT 4500 MARTIN ST
2 2026-01-01T10:02:00 THEFT 1500 E PRESIDIO ST
3 2026-01-01T11:07:00 THEFT 8200 CHAPIN RD
4 2026-01-01T14:17:00 THEFT 1900 THISTLE HILL DR
(1000, 19)
True
{'count': 9428}
def get_crimes(where):
rows = []
offset = 0
while True:
page = requests.get(endpoint, params = {
'where': where, 'outFields': '*',
'orderByFields': 'ObjectId',
'resultOffset': offset, 'f': 'json'
}).json()
rows.extend([f['attributes'] for f in page['features']])
if not page.get('exceededTransferLimit'):
break
offset = offset + 1000
return pd.DataFrame(rows)Nature_Of_Call
THEFT 118
NARCOTIC VIOLATIONS 81
PENAL CODE 79
CRIMINAL MISCHIEF 52
ASSAULT 48
Name: count, dtype: int64
Nature_Of_Call
THEFT 44
DWI 23
PENAL CODE 22
CRIMINAL MISCHIEF 10
CRIMINAL TRESPASS 7
Name: count, dtype: int64
html5lib, BeautifulSoup, lxml, scrapypandas with the read_html() function (for tables)
pandas 2026-2027
0 1MNCManchester City
1 2ARSArsenal
2 3BHABrighton & Hove Albion
3 4LIVLiverpool
4 5CHEChelsea
We get back a list of data frame objects with team names (with clean-up required) in the first data frame and team performance in the second
'^[0-9]+[A-Z]{3}': at the start of the string (^), one or more digits ([0-9]+), then three capital letters ([A-Z]{3}) 2026-2027 name
0 1MNCManchester City 1MNCManchester City
1 2ARSArsenal 2ARSArsenal
2 3BHABrighton & Hove Albion 3BHABrighton & Hove Albion
3 4LIVLiverpool 4LIVLiverpool
4 5CHEChelsea 5CHEChelsea
pandas looked for that text literally name
0 Manchester City
1 Arsenal
2 Brighton & Hove Albion
3 Liverpool
4 Chelsea
concat() function in pandas: stitches together data frames vertically (axis = 0) or horizontally (axis = 1); relies on row/column indices rather than key field value name GP W D L F A GD P
0 Manchester City 8 7 0 1 20 9 11 21
1 Arsenal 8 7 0 1 13 5 8 21
2 Brighton & Hove Albion 8 5 1 2 23 7 16 16
3 Liverpool 8 4 3 1 11 8 3 15
4 Chelsea 8 4 1 3 17 15 2 13
.to_xxx() suite of methods allow you to write pandas data frames to a host of different formatsFor example:
robots.txt# excerpt
User-agent: GPTBot
Disallow: /
User-agent: Google-Extended
Disallow: /
User-agent: CCBot
Disallow: /
User-agent: ChatGPT-User
Disallow: /
User-agent: anthropic-ai
Disallow: /
HTTPError: HTTP Error 403: Forbidden
Municipality 2025 Estimate[7] 2020–2025 Change
0 Houston 2397315.0 +4.16%
1 San Antonio 1548422.0 +7.93%
2 Dallas 1329491.0 +1.93%
3 Fort Worth 1028117.0 +11.88%
4 Austin 1002632.0 +4.24%
5 El Paso 683012.0 +0.62%
HTTPError: HTTP Error 403: Forbidden
robots.txtGEOG 30323 | Data Analysis & Visualization