{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "### Updated: Using Pandas to Create and Excel Diff\n", "\n", "The [original article](http://pbpython.com/excel-diff-pandas.html) contains some Updating the Excel diff article to work with more recent versions of pandas that no longer use panel.\n", "\n", "The new article can be read [here](http://pbpython.com/excel-diff-pandas-update.html)" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import pandas as pd" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# Define the diff function to show the changes in each field\n", "def report_diff(x):\n", " return x[0] if x[0] == x[1] else '{} ---> {}'.format(*x)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# Read in the two files but call the data old and new and create columns to track\n", "old = pd.read_excel('sample-address-1.xlsx', 'Sheet1', na_values=['NA'])\n", "new = pd.read_excel('sample-address-2.xlsx', 'Sheet1', na_values=['NA'])\n", "old['version'] = \"old\"\n", "new['version'] = \"new\"" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
account numbernamestreetcitystatepostal codeversion
0935480Bruen Group5131 Nienow Viaduct Apt. 290Port ArlieAlabama14118old
1371770Cruickshank-Boyer839 Lana Expressway Suite 234South VivianaAlabama57838old
2548367Spencer, Grady and Herman65387 Lang Circle Apt. 516GreenholtburyAlaska58394old
3296620Schamberger, Hagenes and Brown26340 Ferry Neck Apt. 612McCulloughstadAlaska74052old
4132971Williamson, Schumm and Hettinger89403 Casimer SpringJeremieburghArkansas62785old
\n", "
" ], "text/plain": [ " account number name \\\n", "0 935480 Bruen Group \n", "1 371770 Cruickshank-Boyer \n", "2 548367 Spencer, Grady and Herman \n", "3 296620 Schamberger, Hagenes and Brown \n", "4 132971 Williamson, Schumm and Hettinger \n", "\n", " street city state postal code \\\n", "0 5131 Nienow Viaduct Apt. 290 Port Arlie Alabama 14118 \n", "1 839 Lana Expressway Suite 234 South Viviana Alabama 57838 \n", "2 65387 Lang Circle Apt. 516 Greenholtbury Alaska 58394 \n", "3 26340 Ferry Neck Apt. 612 McCulloughstad Alaska 74052 \n", "4 89403 Casimer Spring Jeremieburgh Arkansas 62785 \n", "\n", " version \n", "0 old \n", "1 old \n", "2 old \n", "3 old \n", "4 old " ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "old.head()" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
account numbernamestreetcitystatepostal codeversion
0935480Bruen Group5131 Nienow Viaduct Apt. 290Port ArlieAlabama14118new
1371770Cruickshank-Boyer839 Lana Expressway Suite 234South VivianaAlabama57838new
2548367Spencer, Grady and Herman65387 Lang Circle Apt. 516GreenholtburyAlaska58394new
3132971Williamson, Schumm and Hettinger89403 Casimer SpringJeremieburghArkansas62785new
4985603Bosco-Upton03369 Moe WayPort CasandraArkansas86014new
\n", "
" ], "text/plain": [ " account number name \\\n", "0 935480 Bruen Group \n", "1 371770 Cruickshank-Boyer \n", "2 548367 Spencer, Grady and Herman \n", "3 132971 Williamson, Schumm and Hettinger \n", "4 985603 Bosco-Upton \n", "\n", " street city state postal code version \n", "0 5131 Nienow Viaduct Apt. 290 Port Arlie Alabama 14118 new \n", "1 839 Lana Expressway Suite 234 South Viviana Alabama 57838 new \n", "2 65387 Lang Circle Apt. 516 Greenholtbury Alaska 58394 new \n", "3 89403 Casimer Spring Jeremieburgh Arkansas 62785 new \n", "4 03369 Moe Way Port Casandra Arkansas 86014 new " ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "new.head()" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "# We use the account numbers as the keys to check what is added, dropped and potentially changed\n", "# Using sets makes the deduping easy and we can use set operations to figure out groupings\n", "old_accts_all = set(old['account number'])\n", "new_accts_all = set(new['account number'])\n", "\n", "dropped_accts = old_accts_all - new_accts_all\n", "added_accts = new_accts_all - old_accts_all" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "#Join all the data together and ignore indexes so it all gets concatenated\n", "all_data = pd.concat([old,new],ignore_index=True)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
account numbernamestreetcitystatepostal codeversion
0935480Bruen Group5131 Nienow Viaduct Apt. 290Port ArlieAlabama14118old
1371770Cruickshank-Boyer839 Lana Expressway Suite 234South VivianaAlabama57838old
2548367Spencer, Grady and Herman65387 Lang Circle Apt. 516GreenholtburyAlaska58394old
3296620Schamberger, Hagenes and Brown26340 Ferry Neck Apt. 612McCulloughstadAlaska74052old
4132971Williamson, Schumm and Hettinger89403 Casimer SpringJeremieburghArkansas62785old
\n", "
" ], "text/plain": [ " account number name \\\n", "0 935480 Bruen Group \n", "1 371770 Cruickshank-Boyer \n", "2 548367 Spencer, Grady and Herman \n", "3 296620 Schamberger, Hagenes and Brown \n", "4 132971 Williamson, Schumm and Hettinger \n", "\n", " street city state postal code \\\n", "0 5131 Nienow Viaduct Apt. 290 Port Arlie Alabama 14118 \n", "1 839 Lana Expressway Suite 234 South Viviana Alabama 57838 \n", "2 65387 Lang Circle Apt. 516 Greenholtbury Alaska 58394 \n", "3 26340 Ferry Neck Apt. 612 McCulloughstad Alaska 74052 \n", "4 89403 Casimer Spring Jeremieburgh Arkansas 62785 \n", "\n", " version \n", "0 old \n", "1 old \n", "2 old \n", "3 old \n", "4 old " ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "all_data.head()" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "# Let's see what changes in the main columns we care about\n", "# Change drop_duplicates syntax: keep=last\n", "changes = all_data.drop_duplicates(subset=[\"account number\", \n", " \"name\", \"street\", \n", " \"city\",\"state\", \n", " \"postal code\"], keep='last')" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
account numbernamestreetcitystatepostal codeversion
3296620Schamberger, Hagenes and Brown26340 Ferry Neck Apt. 612McCulloughstadAlaska74052old
24595932Kuhic, Eichmann and West4059 Tobias InletNew RylanfurtIllinois89271old
30558879Watsica Group95616 Enos Grove Suite 139West AtlasIowa47419old
96880043Beatty Inc3641 Schaefer Isle Suite 171North GardnertownWyoming64318old
100935480Bruen Group5131 Nienow Viaduct Apt. 290Port ArlieAlabama14118new
\n", "
" ], "text/plain": [ " account number name \\\n", "3 296620 Schamberger, Hagenes and Brown \n", "24 595932 Kuhic, Eichmann and West \n", "30 558879 Watsica Group \n", "96 880043 Beatty Inc \n", "100 935480 Bruen Group \n", "\n", " street city state postal code \\\n", "3 26340 Ferry Neck Apt. 612 McCulloughstad Alaska 74052 \n", "24 4059 Tobias Inlet New Rylanfurt Illinois 89271 \n", "30 95616 Enos Grove Suite 139 West Atlas Iowa 47419 \n", "96 3641 Schaefer Isle Suite 171 North Gardnertown Wyoming 64318 \n", "100 5131 Nienow Viaduct Apt. 290 Port Arlie Alabama 14118 \n", "\n", " version \n", "3 old \n", "24 old \n", "30 old \n", "96 old \n", "100 new " ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "changes.head()" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "#Get all the duplicate rows\n", "dupe_accts = changes[changes['account number'].duplicated() == True]['account number'].tolist()\n", "dupes = changes[changes[\"account number\"].isin(dupe_accts)]" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
account numbernamestreetcitystatepostal codeversion
24595932Kuhic, Eichmann and West4059 Tobias InletNew RylanfurtIllinois89271old
30558879Watsica Group95616 Enos Grove Suite 139West AtlasIowa47419old
96880043Beatty Inc3641 Schaefer Isle Suite 171North GardnertownWyoming64318old
123595932Kuhic, Eichmann and West4059 Tobias StNew RylanfurtIllinois89271new
129558879Watsica Group829 Big streetSmithtownOhio47919new
195880043Beatty Inc3641 Schaefer Isle Suite 171North GardnertownWyoming64918new
\n", "
" ], "text/plain": [ " account number name street \\\n", "24 595932 Kuhic, Eichmann and West 4059 Tobias Inlet \n", "30 558879 Watsica Group 95616 Enos Grove Suite 139 \n", "96 880043 Beatty Inc 3641 Schaefer Isle Suite 171 \n", "123 595932 Kuhic, Eichmann and West 4059 Tobias St \n", "129 558879 Watsica Group 829 Big street \n", "195 880043 Beatty Inc 3641 Schaefer Isle Suite 171 \n", "\n", " city state postal code version \n", "24 New Rylanfurt Illinois 89271 old \n", "30 West Atlas Iowa 47419 old \n", "96 North Gardnertown Wyoming 64318 old \n", "123 New Rylanfurt Illinois 89271 new \n", "129 Smithtown Ohio 47919 new \n", "195 North Gardnertown Wyoming 64918 new " ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dupes" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "# Pull out the old and new data into separate dataframes\n", "change_new = dupes[(dupes[\"version\"] == \"new\")]\n", "change_old = dupes[(dupes[\"version\"] == \"old\")]" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "# Drop the temp columns - we don't need them now\n", "change_new = change_new.drop(['version'], axis=1)\n", "change_old = change_old.drop(['version'], axis=1)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "# Index on the account numbers\n", "change_new.set_index('account number', inplace=True)\n", "change_old.set_index('account number', inplace=True)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "df_all_changes = pd.concat([change_old, change_new],\n", " axis='columns',\n", " keys=['old', 'new'],\n", " join='outer')" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
oldnew
namestreetcitystatepostal codenamestreetcitystatepostal code
account number
595932Kuhic, Eichmann and West4059 Tobias InletNew RylanfurtIllinois89271Kuhic, Eichmann and West4059 Tobias StNew RylanfurtIllinois89271
558879Watsica Group95616 Enos Grove Suite 139West AtlasIowa47419Watsica Group829 Big streetSmithtownOhio47919
880043Beatty Inc3641 Schaefer Isle Suite 171North GardnertownWyoming64318Beatty Inc3641 Schaefer Isle Suite 171North GardnertownWyoming64918
\n", "
" ], "text/plain": [ " old \\\n", " name street \n", "account number \n", "595932 Kuhic, Eichmann and West 4059 Tobias Inlet \n", "558879 Watsica Group 95616 Enos Grove Suite 139 \n", "880043 Beatty Inc 3641 Schaefer Isle Suite 171 \n", "\n", " \\\n", " city state postal code \n", "account number \n", "595932 New Rylanfurt Illinois 89271 \n", "558879 West Atlas Iowa 47419 \n", "880043 North Gardnertown Wyoming 64318 \n", "\n", " new \\\n", " name street \n", "account number \n", "595932 Kuhic, Eichmann and West 4059 Tobias St \n", "558879 Watsica Group 829 Big street \n", "880043 Beatty Inc 3641 Schaefer Isle Suite 171 \n", "\n", " \n", " city state postal code \n", "account number \n", "595932 New Rylanfurt Illinois 89271 \n", "558879 Smithtown Ohio 47919 \n", "880043 North Gardnertown Wyoming 64918 " ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_all_changes" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [], "source": [ "df_all_changes = df_all_changes.swaplevel(axis='columns')[change_new.columns[0:]]" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
namestreetcitystatepostal code
oldnewoldnewoldnewoldnewoldnew
account number
595932Kuhic, Eichmann and WestKuhic, Eichmann and West4059 Tobias Inlet4059 Tobias StNew RylanfurtNew RylanfurtIllinoisIllinois8927189271
558879Watsica GroupWatsica Group95616 Enos Grove Suite 139829 Big streetWest AtlasSmithtownIowaOhio4741947919
880043Beatty IncBeatty Inc3641 Schaefer Isle Suite 1713641 Schaefer Isle Suite 171North GardnertownNorth GardnertownWyomingWyoming6431864918
\n", "
" ], "text/plain": [ " name \\\n", " old new \n", "account number \n", "595932 Kuhic, Eichmann and West Kuhic, Eichmann and West \n", "558879 Watsica Group Watsica Group \n", "880043 Beatty Inc Beatty Inc \n", "\n", " street \\\n", " old new \n", "account number \n", "595932 4059 Tobias Inlet 4059 Tobias St \n", "558879 95616 Enos Grove Suite 139 829 Big street \n", "880043 3641 Schaefer Isle Suite 171 3641 Schaefer Isle Suite 171 \n", "\n", " city state \\\n", " old new old new \n", "account number \n", "595932 New Rylanfurt New Rylanfurt Illinois Illinois \n", "558879 West Atlas Smithtown Iowa Ohio \n", "880043 North Gardnertown North Gardnertown Wyoming Wyoming \n", "\n", " postal code \n", " old new \n", "account number \n", "595932 89271 89271 \n", "558879 47419 47919 \n", "880043 64318 64918 " ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_all_changes" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [], "source": [ "df_changed = df_all_changes.groupby(level=0, axis=1).apply(lambda frame: frame.apply(report_diff, axis=1))\n", "df_changed = df_changed.reset_index()" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
account numbercitynamepostal codestatestreet
0595932New RylanfurtKuhic, Eichmann and West89271Illinois4059 Tobias Inlet ---> 4059 Tobias St
1558879West Atlas ---> SmithtownWatsica Group47419 ---> 47919Iowa ---> Ohio95616 Enos Grove Suite 139 ---> 829 Big street
2880043North GardnertownBeatty Inc64318 ---> 64918Wyoming3641 Schaefer Isle Suite 171
\n", "
" ], "text/plain": [ " account number city name \\\n", "0 595932 New Rylanfurt Kuhic, Eichmann and West \n", "1 558879 West Atlas ---> Smithtown Watsica Group \n", "2 880043 North Gardnertown Beatty Inc \n", "\n", " postal code state \\\n", "0 89271 Illinois \n", "1 47419 ---> 47919 Iowa ---> Ohio \n", "2 64318 ---> 64918 Wyoming \n", "\n", " street \n", "0 4059 Tobias Inlet ---> 4059 Tobias St \n", "1 95616 Enos Grove Suite 139 ---> 829 Big street \n", "2 3641 Schaefer Isle Suite 171 " ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_changed" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [], "source": [ "# Diff'ing is done, we need to get a list of removed and added items" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
account numbernamestreetcitystatepostal codeversion
3296620Schamberger, Hagenes and Brown26340 Ferry Neck Apt. 612McCulloughstadAlaska74052old
\n", "
" ], "text/plain": [ " account number name street \\\n", "3 296620 Schamberger, Hagenes and Brown 26340 Ferry Neck Apt. 612 \n", "\n", " city state postal code version \n", "3 McCulloughstad Alaska 74052 old " ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_removed = changes[changes[\"account number\"].isin(dropped_accts)]\n", "df_removed" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
account numbernamestreetcitystatepostal codeversion
19934777MyCo7833 Old Pine DriveOrlandoFlorida32789new
\n", "
" ], "text/plain": [ " account number name street city state postal code \\\n", "199 34777 MyCo 7833 Old Pine Drive Orlando Florida 32789 \n", "\n", " version \n", "199 new " ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_added = changes[changes[\"account number\"].isin(added_accts)]\n", "df_added" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": [ "#Save the changes to excel but only include the columns we care about\n", "output_columns = [\"account number\", \"name\", \"street\", \"city\", \"state\", \"postal code\"]\n", "writer = pd.ExcelWriter(\"my-diff.xlsx\")\n", "df_changed.to_excel(writer,\"changed\", index=False, columns=output_columns)\n", "df_removed.to_excel(writer,\"removed\",index=False, columns=output_columns)\n", "df_added.to_excel(writer,\"added\",index=False, columns=output_columns)\n", "writer.save()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.5" } }, "nbformat": 4, "nbformat_minor": 2 }