Skip to content

Commit 3391c7d

Browse files
committed
Refactor code and structure to polars
1 parent af97f71 commit 3391c7d

2 files changed

Lines changed: 264 additions & 4563 deletions

File tree

‎data-transform.ipynb‎

Lines changed: 31 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@
183183
"Note: If you're coming from **pandas**, be aware that **polars** does not use an index column and each row is indexed by its integer position in the table.\n",
184184
":::\n",
185185
"\n",
186-
"![](https://pandas.pydata.org/docs/_images/01_table_dataframe.svg)\n"
186+
"![](./dataframe_illustration.svg)\n"
187187
]
188188
},
189189
{
@@ -650,7 +650,7 @@
650650
"metadata": {},
651651
"source": [
652652
"We can use `.alias()` with an expression to assign column names, when creating new columns.\n",
653-
"The other way to do this involves an 'assign()' statement and is used when you wish to chain multiple steps together (like we saw earlier). These use a special syntax called a 'lambda' statement, which (here at least) just provides a way of specifying to **pandas** that we wish to perform the operation on every row. Below is an example using the flights data. You should note though that the word 'row' below is a dummy; you could replace it with any variable name (for example, `x`) but `row` makes what is happening a little bit clearer.\n"
653+
"We can chain multiple expressions together with `.with_columns()`, which would create multiple new columns with the names assigned to `.alias()`.\n"
654654
]
655655
},
656656
{
@@ -900,7 +900,7 @@
900900
"\n",
901901
"The simplest way to re-order (all) columns is to create a new list of their names with them in the order that you'd like them: but be careful you don't forget any columns that you'd like to keep!\n",
902902
"\n",
903-
"Let's see an example with a fresh version of the fake data from earlier. We'll put all of the odd-numbered columns first, in descending order, then the even similarly.\n"
903+
"Let's see an example with a fresh version of the fake data from earlier. We'll put all of the odd-numbered columns first, in descending order, then the even similarly using `.select()`.\n"
904904
]
905905
},
906906
{
@@ -912,20 +912,19 @@
912912
"source": [
913913
"df = pl.DataFrame(\n",
914914
" data=np.reshape(range(36), (6, 6)),\n",
915-
" columns=[\"col\" + str(i) for i in range(6)],\n",
916-
" dtype=float,\n",
915+
" schema=[\"col\" + str(i) for i in range(6)]\n",
917916
")\n",
918917
"df"
919918
]
920919
},
921920
{
922921
"cell_type": "code",
923922
"execution_count": null,
924-
"id": "b9a409ac",
923+
"id": "3c2029cc",
925924
"metadata": {},
926925
"outputs": [],
927926
"source": [
928-
"df = df[[\"col5\", \"col3\", \"col1\", \"col4\", \"col2\", \"col0\"]]\n",
927+
"df = df.select([\"col5\", \"col3\", \"col1\", \"col4\", \"col2\", \"col0\"])\n",
929928
"df"
930929
]
931930
},
@@ -934,7 +933,7 @@
934933
"id": "dd91d87a",
935934
"metadata": {},
936935
"source": [
937-
"Of course, this is quite tedious if you have lots of columns! There are methods that can help make this easier depending on your context. Perhaps you'd just liked to sort the columns in order? This can be achieved by combining `sorted()` and the `reindex()` command (which works for rows or columns) with `axis=1`, which means the second axis (i.e. columns).\n"
936+
"Of course, this is quite tedious if you have lots of columns! There are methods that can help make this easier depending on your context. Perhaps you'd just liked to sort the columns in order? This can be achieved by combining `sorted()` and the `.select()` function, passing the DataFrame `.columns`.\n"
938937
]
939938
},
940939
{
@@ -944,7 +943,11 @@
944943
"metadata": {},
945944
"outputs": [],
946945
"source": [
947-
"df.reindex(sorted(df.columns), axis=1)"
946+
"# Alphabetical order\n",
947+
"df.select(sorted(df.columns))\n",
948+
"\n",
949+
"# Reverse alphabetical order\n",
950+
"df.select(sorted(df.columns, reverse=True))"
948951
]
949952
},
950953
{
@@ -954,37 +957,21 @@
954957
"source": [
955958
"### Column and Row Exercises\n",
956959
"\n",
957-
"1. Compare `air_time` with `arr_time - dep_time`. What do you expect to see? What do you see What do you need to do to fix it?\n",
960+
"1. Compare `air_time` with `arr_time - dep_time`. What do you expect to see? What do you see? What do you need to do to fix it?\n",
958961
"\n",
959962
"2. Compare `dep_time`, `sched_dep_time`, and `dep_delay`. How would you expect those three numbers to be related?\n",
960963
"\n",
961964
"3. Brainstorm as many ways as possible to select `dep_time`, `dep_delay`, `arr_time`, and `arr_delay` from `flights`.\n",
962965
"\n",
963-
"4. What happens if you include the name of a row or column multiple times when trying to select them?\n",
964-
"\n",
965-
"5. What does the `.isin()` function do in the following?\n",
966-
"\n",
967-
" ```python\n",
968-
" flights.columns.isin([\"year\", \"month\", \"day\", \"dep_delay\", \"arr_delay\"])\n",
969-
" ```\n",
970-
"\n",
971-
"6. Does the result of running the following code surprise you?\n",
972-
" How do functions like `str.contains` deal with case by default?\n",
973-
" How can you change that default?\n",
974-
"\n",
975-
" ```python\n",
976-
" flights.loc[:, flights.columns.str.contains(\"TIME\")]\n",
977-
" ```\n",
978-
"\n",
979-
" (Hint: you can use help even on functions that apply to data frames, eg use `help(flights.columns.str.contains)`)\n"
966+
"4. What happens if you include the name of a row or column multiple times when trying to select them?\n"
980967
]
981968
},
982969
{
983970
"cell_type": "markdown",
984971
"id": "a3c837e4",
985972
"metadata": {},
986973
"source": [
987-
"## Grouping, changing the index, and applying summary statistics\n",
974+
"## Grouping and applying summary statistics\n",
988975
"\n",
989976
"So far you've learned about working with rows and columns. **polars** gets even more powerful when you add in the ability to work with groups. And because groups tend to imply an aggregation or pooling of data, they go hand-in-glove with the application of a summary statistic.\n",
990977
"\n",
@@ -999,50 +986,12 @@
999986
},
1000987
{
1001988
"cell_type": "code",
1002-
"execution_count": 92,
989+
"execution_count": null,
1003990
"id": "62e540c0",
1004991
"metadata": {},
1005-
"outputs": [
1006-
{
1007-
"data": {
1008-
"text/html": [
1009-
"<div><style>\n",
1010-
".dataframe > thead > tr,\n",
1011-
".dataframe > tbody > tr {\n",
1012-
" text-align: right;\n",
1013-
" white-space: pre-wrap;\n",
1014-
"}\n",
1015-
"</style>\n",
1016-
"<small>shape: (12, 2)</small><table border=\"1\" class=\"dataframe\"><thead><tr><th>month</th><th>dep_delay</th></tr><tr><td>i64</td><td>f64</td></tr></thead><tbody><tr><td>11</td><td>5.435362</td></tr><tr><td>12</td><td>16.576688</td></tr><tr><td>2</td><td>10.816843</td></tr><tr><td>8</td><td>12.61104</td></tr><tr><td>10</td><td>6.243988</td></tr><tr><td>&hellip;</td><td>&hellip;</td></tr><tr><td>6</td><td>20.846332</td></tr><tr><td>1</td><td>10.036665</td></tr><tr><td>7</td><td>21.727787</td></tr><tr><td>3</td><td>13.227076</td></tr><tr><td>5</td><td>12.986859</td></tr></tbody></table></div>"
1017-
],
1018-
"text/plain": [
1019-
"shape: (12, 2)\n",
1020-
"┌───────┬───────────┐\n",
1021-
"│ month ┆ dep_delay │\n",
1022-
"│ --- ┆ --- │\n",
1023-
"│ i64 ┆ f64 │\n",
1024-
"╞═══════╪═══════════╡\n",
1025-
"│ 11 ┆ 5.435362 │\n",
1026-
"│ 12 ┆ 16.576688 │\n",
1027-
"│ 2 ┆ 10.816843 │\n",
1028-
"│ 8 ┆ 12.61104 │\n",
1029-
"│ 10 ┆ 6.243988 │\n",
1030-
"│ … ┆ … │\n",
1031-
"│ 6 ┆ 20.846332 │\n",
1032-
"│ 1 ┆ 10.036665 │\n",
1033-
"│ 7 ┆ 21.727787 │\n",
1034-
"│ 3 ┆ 13.227076 │\n",
1035-
"│ 5 ┆ 12.986859 │\n",
1036-
"└───────┴───────────┘"
1037-
]
1038-
},
1039-
"execution_count": 92,
1040-
"metadata": {},
1041-
"output_type": "execute_result"
1042-
}
1043-
],
1044-
"source": [
1045-
"flights.group_by(\"month\").agg(pl.mean(\"dep_delay\"))"
992+
"outputs": [],
993+
"source": [
994+
"flights.group_by(\"month\").agg(pl.col(\"dep_delay\").mean())"
1046995
]
1047996
},
1048997
{
@@ -1062,13 +1011,14 @@
10621011
"source": [
10631012
"| Aggregation | Description |\n",
10641013
"| -------------------- | ------------------------------- |\n",
1065-
"| `count()` | Number of items |\n",
1014+
"| `count()` | Number of non-null items |\n",
1015+
"| `len()` | Number of all items |\n",
10661016
"| `first()`, `last()` | First and last item |\n",
10671017
"| `mean()`, `median()` | Mean and median |\n",
10681018
"| `min()`, `max()` | Minimum and maximum |\n",
10691019
"| `std()`, `var()` | Standard deviation and variance |\n",
10701020
"| `mad()` | Mean absolute deviation |\n",
1071-
"| `prod()` | Product of all items |\n",
1021+
"| `product()` | Product of all items |\n",
10721022
"| `sum()` | Sum of all items |\n",
10731023
"| `value_counts()` | Counts of unique values |\n",
10741024
"\n",
@@ -1082,11 +1032,10 @@
10821032
"metadata": {},
10831033
"outputs": [],
10841034
"source": [
1085-
"(\n",
1086-
" flights.group_by(\"month\").agg(\n",
1087-
" mean_delay=pl.mean(\"dep_delay\"),\n",
1088-
" count_flights=pl.count(\"dep_delay\"),\n",
1089-
" )\n",
1035+
"# Multiple aggregations using polars' syntactic sugar (shorthand) for mean and count\n",
1036+
"flights.group_by(\"month\").agg(\n",
1037+
" mean_delay=pl.mean(\"dep_delay\"),\n",
1038+
" count_flights=pl.count(\"dep_delay\"),\n",
10901039
")"
10911040
]
10921041
},
@@ -1105,7 +1054,7 @@
11051054
"source": [
11061055
"### Grouping by multiple variables\n",
11071056
"\n",
1108-
"This is as simple as passing `.group_by()` a list representing multiple columns instead of a string representing a single column.\n"
1057+
"This is as simple as passing `.group_by()` a list or multiple strings representing columns instead of a single string representing a single column.\n"
11091058
]
11101059
},
11111060
{
@@ -1115,9 +1064,9 @@
11151064
"metadata": {},
11161065
"outputs": [],
11171066
"source": [
1118-
"month_year_delay = flights.group_by([\"month\", \"year\"]).agg(\n",
1119-
" mean_delay=(\"dep_delay\", \"mean\"),\n",
1120-
" count_flights=(\"dep_delay\", \"count\"),\n",
1067+
"month_year_delay = flights.group_by(\"month\", \"year\").agg(\n",
1068+
" mean_delay=pl.mean(\"dep_delay\"),\n",
1069+
" count_flights=pl.count(\"dep_delay\"),\n",
11211070
")\n",
11221071
"month_year_delay"
11231072
]
@@ -1173,7 +1122,7 @@
11731122
"source": [
11741123
"### Groupby Exercises\n",
11751124
"\n",
1176-
"1. Which carrier has the worst delays? Challenge: can you disentangle the effects of bad airports vs. bad carriers? Why/why not? (Hint: think about `flights.groupby([\"carrier\", \"dest\"]).count()`)\n",
1125+
"1. Which carrier has the worst delays? Challenge: can you disentangle the effects of bad airports vs. bad carriers? Why/why not? (Hint: think about `flights.group_by([\"carrier\", \"dest\"])`)\n",
11771126
"\n",
11781127
"2. Find the most delayed flight to each destination.\n",
11791128
"\n",

0 commit comments

Comments
 (0)