In the print dialog, choose "Save as PDF" as the destination.
Machine Learning, Week 1
Load data from CSV, text, Excel, HTML and JSON into a DataFrame, then filter, group, clean, join and reshape it.
sep, header, names, skiprows, skipfooter and nrowsloc and a boolean mask, and summarise columns with describepivot_table to aggregate, and apply to create new columnsisnull, fillna and dropnaconcat, merge and joinWeek 1 of the plan
| Part | What we do | Time |
|---|---|---|
| 1 | Reading data from many sources | 35 min |
| 2 | Selecting, filtering and grouping | 25 min |
| 3 | Missing values, joins and reshaping | 25 min |
| 4 | Common mistakes and the project milestone | 5 min |
| 5 | Practice with answers, then takeaways | 30 min |
Part 1
One function per format, one DataFrame at the end
| Source | pandas function | Returns |
|---|---|---|
| CSV, zipped CSV | pd.read_csv | a DataFrame |
| Other delimited text | pd.read_table | a DataFrame |
| Excel workbook | pd.read_excel | a DataFrame, or a dict of them |
| Tables in a web page | pd.read_html | a list of DataFrames |
| JSON file | pd.read_json | a DataFrame |
base = ("https://raw.githubusercontent.com/tirthajyoti/"
"Machine-Learning-with-Python/master/Pandas%20and%20Numpy/"
"Read_data_various_sources/")
df1 = pd.read_csv(base + "CSV_EX_1.csv")
df1.shape # (5, 4)CSV_EX_1.csv, five houses
Bedroom, Sq. foot, Locality, Price ($)
2, 1500, Good, 300000
3, 1300, Fair, 240000
3, 1900, Very good, 450000
3, 1850, Bad, 280000
2, 1640, Good, 310000df1 = pd.read_csv("CSV_EX_1.csv")
df1.shape # (5, 4)int64, words stay textCSV_EX_2.csv holds the same five houses, without the header line
2 1500 Good 300000
0 3 1300 Fair 240000
1 3 1900 Very good 450000
2 3 1850 Bad 280000
3 2 1640 Good 310000df2 = pd.read_csv("CSV_EX_2.csv",
header=None,
names=['Bedroom', 'Sq.ft',
'Locality', 'Price($)']) Bedroom Sq.ft Locality Price($)
0 2 1500 Good 300000
1 3 1300 Fair 240000
2 3 1900 Very good 450000
3 3 1850 Bad 280000
4 2 1640 Good 310000CSV_EX_3.csv: Bedroom; Sq. foot; Locality; Price ($)
df3.shape is (5, 1): no comma, so each line stays one text valuepd.read_csv("CSV_EX_3.csv", sep=';'), which gives (5, 4)CSV_EX_skipfooter.csv
Filetype: CSV,,,
,Info about some houses,,
Bedroom, Sq. foot, Locality, Price ($)
2,1500, Good,300000
...
2,1640, Good,310000
, This is the end of file,,Filetype: CSV, Unnamed: 1, Unnamed: 2, Unnamed: 3skiprows=2, skipfooter=1, engine='python' gives the clean (5, 4)rows_in_a_chunk = 10
num_chunks = 5
colnames = pd.read_csv("Boston_housing.csv", nrows=2).columns
list_of_dataframe = []
for i in range(0, num_chunks*rows_in_a_chunk, rows_in_a_chunk):
df = pd.read_csv("Boston_housing.csv", header=0, skiprows=i,
nrows=rows_in_a_chunk, names=colnames)
list_of_dataframe.append(df)nrows=2 reads only the first 2 rowsi lines and reads the next 10CSV_EX_blankline.csv has two empty lines between the houses
| Option | Shape | What you see |
|---|---|---|
default (True) | (5, 4) | blank lines are skipped |
skip_blank_lines=False | (7, 4) | two rows of NaN, and 2 becomes 2.0 |
pd.read_csv("CSV_EX_1.zip") sees the .zip extension and unzips on the flycompression defaults to 'infer'CSV_EX_1.csv readpd.read_excel("Housing_data.xlsx", sheet_name='Data_Tab_1')| Sheet | Shape |
|---|---|
Data_Tab_1 | (9, 14) |
Data_Tab_2 | (4, 14) |
Data_Tab_3 | (16, 14) |
pd.read_table("Table_tab_separated.txt") # (5, 4)
pd.read_table("Table_EX_1.txt") # (5, 1)
pd.read_table("Table_EX_1.txt", sep=',') # (5, 4)read_table is read_csv with a tab as the default sepTable_tab_separated.txt uses tabs: a clean (5, 4)Table_EX_1.txt uses commas: one column, (5, 1), until you pass sep=','pd.read_html(url, header=0) returns a list, one DataFrame per HTML table
| Rank | NOC | Gold | Total |
|---|---|---|---|
| 1 | United States | 46 | 121 |
| 2 | Great Britain | 27 | 67 |
| 3 | China | 26 | 70 |
| 4 | Russia‡ | 19 | 56 |
| 5 | Germany | 17 | 42 |
[
{"Bedroom": 2, "Sq. foot": 1500,
"Locality": "Good", "Price ($)": 300000},
...
]dj = pd.read_json('houses.json')
dj[dj['Locality'] == 'Good'] # rows 0 and 4read_json turns a list of records into rows: the same (5, 4) tablepd.read_stata("rscfp2016.dta") reads a Stata data file the same wayread_pdf from the separate tabula-py package extracts tables from PDF pagesnames through pandas_optionsPart 2
The Advanced Pandas Operations notebook, on the superstore orders
https://colab.research.google.com/github/
tirthajyoti/Machine-Learning-with-Python/blob/master/
Pandas%20and%20Numpy/Advanced%20Pandas%20Operations.ipynbSample - Superstore.xls from its own folder, which Colab does not haveurl = ("https://raw.githubusercontent.com/tirthajyoti/"
"Machine-Learning-with-Python/master/"
"Pandas%20and%20Numpy/Sample%20-%20Superstore.xls")
df = pd.read_excel(url)
df.shape # (9994, 21)
df.drop('Row ID', axis=1, inplace=True)
df.shape # (9994, 20)Sales, Quantity, Discount, ProfitOrders, Returns, People, Missingloc takes a list of index labels and a list of column names
df.loc[[i for i in range(5, 10)],
['Customer ID', 'City', 'Postal Code', 'Sales']]| Row | Customer ID | City | Sales |
|---|---|---|---|
| 5 | BH-11710 | Los Angeles | 48.860 |
| 6 | BH-11710 | Los Angeles | 7.280 |
| 7 | BH-11710 | Los Angeles | 907.152 |
| 8 | BH-11710 | Los Angeles | 18.504 |
| 9 | BH-11710 | Los Angeles | 114.900 |
df_subset = df.loc[[i for i in
range(100, 200)], ['Sales', 'Profit']]
df_subset.describe()| Statistic | Sales | Profit |
|---|---|---|
| mean | 262.957 | 0.348 |
| std | 858.984 | 170.745 |
| min | 1.788 | -1359.992 |
| 50% (median) | 66.960 | 9.654 |
| max | 8159.952 | 585.552 |

df_subset.plot.box() draws one box per columnplt.ylim(0, 500) zooms in: 12 sales and 1 profit above 500, and 20 negative profits, are off the chartdf_subset.plot.box()
plt.ylim(0, 500)
plt.grid(True)df_subset = df.loc[[i for i in range(10)], ['Ship Mode', 'State', 'Sales']]
Ship Mode State Sales
0 Second Class Kentucky 261.9600
1 Second Class Kentucky 731.9400
2 Second Class California 14.6200
3 Standard Class Florida 957.5775
4 Standard Class Florida 22.3680
5 Standard Class California 48.8600
6 Standard Class California 7.2800
7 Standard Class California 907.1520
8 Standard Class California 18.5040
9 Standard Class California 114.9000df_subset[(df_subset['State'] != 'California') & (df_subset['Sales'] > 100)]& means both, | means either, and each condition needs its own parenthesesSplit
rows by State
Apply
mean of each group
Combine
one row per State
byState = df_subset.groupby('State')
byState.mean(numeric_only=True)| Notebook code | Today | Write instead |
|---|---|---|
byState.mean() | TypeError: text columns cannot be averaged | byState.mean(numeric_only=True) |
byState.sum() | glues the Ship Mode text together | byState.sum(numeric_only=True) |
byState['Sales'].mean() | works | the same, as a Series |
Part 3
The Missing sheet and small slices of the orders
df_missing = pd.read_excel(url, sheet_name='Missing')
for c in df_missing.columns:
miss = df_missing[c].isnull().sum()
if miss > 0:
print('{} has {} missing value(s)'.format(c, miss))
else:
print('{} has NO missing value!'.format(c))Customer has 1 missing value(s)
Product has 2 missing value(s)
Sales has 1 missing value(s)
Quantity has 1 missing value(s)
Discount has NO missing value!
Profit has 1 missing value(s)Sales rows 2 to 4 are 8.560, NaN, 22.720; the other 10 values add up to 3015.52
ffill() copies the value above: 8.56bfill() copies the value below: 22.72| Call | What survives |
|---|---|
dropna(axis=0) | ? |
dropna(axis=1) | ? |
dropna(axis=1, thresh=10) | ? |
axis=0: the 6 rows with no gap (1, 2, 4, 6, 9, 10)axis=1: only Discount, the one full columnthresh=10: columns with at least 10 values, so only Product is dropped
Three tables of 2 orders each, columns Customer ID, State, Sales, Profit, rows 0 to 5
axis=0 stacks rows: (6, 4)axis=1 puts the tables side by side, matched on the index: (6, 12)axis=1 leaves 48 of the 72 cells NaNdf_1 and df_2: rows 0 to 3, keys CG-12520 twice, DV-13045, SO-20335
pd.merge(df_1, df_2, on='Customer ID', how='inner')df_1 with df_3 (rows 2 to 5: DV-13045, SO-20335 twice, BH-11710)
| how | Keeps | Rows |
|---|---|---|
inner | keys in both tables | 3 |
left | every df_1 row | 5 |
right | every df_3 row | 4 |
outer | every key, sorted | 6 |
df.pivot_table(values=['Sales', 'Quantity', 'Profit'], index=['Region'], aggfunc='mean')| Region | Profit | Quantity | Sales |
|---|---|---|---|
| Central | 17.09 | 3.78 | 215.77 |
| East | 32.14 | 3.73 | 238.34 |
| South | 28.86 | 3.83 | 241.80 |
| West | 33.85 | 3.83 | 226.49 |
df['Ship Mode'].value_counts()| Ship Mode | Orders |
|---|---|
| Standard Class | 5968 |
| Second Class | 1945 |
| First Class | 1538 |
| Same Day | 543 |
df_subset.sort_values(by='Sales')
df_subset.sort_values(by=['State', 'Sales'])Sales: row 6 (7.28) comes first and row 3 (957.5775) last['State', 'Sales']: State first, then Sales breaks tiescategorize_sales: Low below 50, Medium below 200, High otherwise
def categorize_sales(price):
if price < 50:
return "Low"
elif price < 200:
return "Medium"
else:
return "High"
df['Sales'].apply(categorize_sales)Part 4
Five minutes before the practice
Before you practise
sep does not match the fileheader=None& or |fillna(method=), mean() on text columns, chained assignmentYour team project
shape, the column names and isnull().sum() before anything elsePart 5
About 30 minutes, answers follow each task
About 5 minutes
Exported by the lab system
Section 3
ID;Name;Quiz;Lab
101;A1;7;9
102;B2;5;8
103;C3;9;10
104;D4;6;7
End of exportpd.read_csv('p1_scores.txt', sep=';', skiprows=2,
skipfooter=1, engine='python')About 8 minutes
Region Ship Mode Sales
0 East First Class 120.0
1 West Standard Class 45.5
2 East Standard Class 310.0
3 South Second Class 80.0
4 West First Class 220.0
5 South Standard Class 15.0
6 East Second Class 95.0
7 West Standard Class 60.5categorize_sales countsAbout 5 minutes
Qty = 4, NaN, 6, NaN, 10 and Price = 2.5, 3.0, NaN, 4.0, 5.5 and Item = pen, ink, None, pad, tape
ffill() and bfill() of Qtydropna(axis=0)? Which columns survive dropna(axis=1, thresh=4)?About 5 minutes
left: Key = K1, K2, K2, K3 with A = 1, 2, 3, 4. right: Key = K2, K3, K3, K4 with B = 10, 20, 30, 40
| how | Rows | Why |
|---|---|---|
inner | 4 | K2: 2 × 1, K3: 1 × 2 |
left | 5 | the 4 inner rows + K1 with NaN |
right | 5 | the 4 inner rows + K4 with NaN |
outer | 6 | the 4 inner rows + K1 + K4 |
About 7 minutes
groupbypivot_table: which region is lowest?Answers
| Question | Answer |
|---|---|
| Texas orders | 985 |
| Sales per Category | Furniture 741999.80, Office Supplies 719047.03, Technology 836154.03 |
| Profit per Category | Furniture 18451.27, Office Supplies 122490.80, Technology 145454.95 |
| Orders with a loss | 1871 |
| Lowest Profit region | Central, 39706.36 |
read_csv, read_table, read_excel, read_html, read_jsonsep or headerpivot_tableisnull, then decide: fill or dropconcat, merge or join, and count the rows afterMahmoud Abas|Advanced Pandas and Reading Data from Many Sources