Import agate, a Python-based data analysis library


In [86]:
import agate

Create agate Table of csv file from Nebraska registered voters data from 2000 to 2014


In [87]:
parties = agate.Table.from_csv('CleanPoliticalData.csv')

Check out column names & types from parties table


In [88]:
print(parties)


|---------------+---------------|
|  column_names | column_types  |
|---------------+---------------|
|  County Name  | Text          |
|  FIPS Code    | Number        |
|  Total2014    | Number        |
|  Total2012    | Number        |
|  Total2010    | Number        |
|  Total2008    | Number        |
|  Total2006    | Number        |
|  Total2004    | Number        |
|  Total2002    | Number        |
|  Total2000    | Number        |
|  NP2014       | Number        |
|  NP2012       | Number        |
|  NP2010       | Number        |
|  NP2008       | Number        |
|  NP2006       | Number        |
|  NP2004       | Number        |
|  NP2002       | Number        |
|  NP2000       | Number        |
|  GOP2014      | Number        |
|  GOP2012      | Number        |
|  GOP2010      | Number        |
|  GOP2008      | Number        |
|  GOP2006      | Number        |
|  GOP2004      | Number        |
|  GOP2002      | Number        |
|  GOP2000      | Number        |
|  Dem2014      | Number        |
|  Dem2012      | Number        |
|  Dem2010      | Number        |
|  Dem2008      | Number        |
|  Dem2006      | Number        |
|  Dem2004      | Number        |
|  Dem2002      | Number        |
|  Dem2000      | Number        |
|---------------+---------------|

Let's see some stats about Nebraska political party distributions and calculate when the independent party would overtake the Democratic Party, given the growth rates continue.

Grab the total row form the parties table


In [26]:
totalRow = parties.where(lambda row: row['County Name'] == 'Total State')
print(len(totalRow.rows))


1

Calculate the percent of each party in 2000


In [61]:
def calculateNP00(row):
    return row['NP2000'] / row['Total2000']
def calculateDem00(row):
    return row['Dem2000'] / row['Total2000']
def calculateGOP00(row):
    return row['GOP2000'] / row['Total2000']

In [62]:
distributions00 = totalRow.compute([
        ('nonparty_distribution2000', agate.Formula(agate.Number(), calculateNP00)),
        ('demparty_distribution2000', agate.Formula(agate.Number(), calculateDem00)),
        ('gopparty_distribution2000', agate.Formula(agate.Number(), calculateGOP00)),
    ])

View each party's percent in 2000


In [64]:
printDistribution00 = distributions00.select(['nonparty_distribution2000', 'demparty_distribution2000', 'gopparty_distribution2000'])
printDistribution00.print_table()


|----------------------------+---------------------------+----------------------------|
|  nonparty_distribution2000 | demparty_distribution2000 | gopparty_distribution2000  |
|----------------------------+---------------------------+----------------------------|
|       0.141066717532069... |      0.361535066258637... |      0.495389401382396...  |
|----------------------------+---------------------------+----------------------------|

Calculate the percent of each party in 2014


In [65]:
def calculateNP14(row):
    return row['NP2014'] / row['Total2014']
def calculateDem14(row):
    return row['Dem2014'] / row['Total2014']
def calculateGOP14(row):
    return row['GOP2014'] / row['Total2014']

In [66]:
distributions14 = totalRow.compute([
        ('nonparty_distribution2014', agate.Formula(agate.Number(), calculateNP14)),
        ('demparty_distribution2014', agate.Formula(agate.Number(), calculateDem14)),
        ('gopparty_distribution2014', agate.Formula(agate.Number(), calculateGOP14)),
    ])

View each party's percent in 2014


In [69]:
printDistribution14 = distributions14.select(['nonparty_distribution2014', 'demparty_distribution2014', 'gopparty_distribution2014'])
printDistribution14.print_table()


|----------------------------+---------------------------+----------------------------|
|  nonparty_distribution2014 | demparty_distribution2014 | gopparty_distribution2014  |
|----------------------------+---------------------------+----------------------------|
|       0.203584619101860... |      0.308787235511373... |      0.482693037865451...  |
|----------------------------+---------------------------+----------------------------|

Calculate how long until the independent party overtakes the Democratic party. Using the Investigative Reporters & Editors' Number in the Newsrooms, I took the average of the last three election years other than the last. Then, I divided the last year by that average. That percent change was taken to the third power, which computes the percent growth in three election cycles or 6 years. Finally, the last year is multiplied by this growth value to find the estimated party numbers 6 years from 2014 or 2020.


In [79]:
def futureNP(row):
    average = (row['NP2012'] + row['NP2010'] + row['NP2008'])/3
    percentChange = row['NP2014'] / average
    change3elections = percentChange ** 3
    futureValue = row['NP2014'] * change3elections
    return futureValue
def futureDem(row):
    average = (row['Dem2012'] + row['Dem2010'] + row['Dem2008'])/3
    percentChange = row['Dem2014'] / average
    change3elections = percentChange ** 3
    futureValue = row['Dem2014'] * change3elections
    return futureValue
def futureGOP(row):
    average = (row['GOP2012'] + row['GOP2010'] + row['GOP2008'])/3
    percentChange = row['GOP2014'] / average
    change3elections = percentChange ** 3
    futureValue = row['GOP2014'] * change3elections
    return futureValue

In [83]:
future = totalRow.compute([
        ('futureNP', agate.Formula(agate.Number(), futureNP)),
        ('futureDem', agate.Formula(agate.Number(), futureDem)),
        ('futureGOP', agate.Formula(agate.Number(), futureGOP)),
    ])

Given the same growth/decline rates, the parties will have the following estimated registered voters in 2020.


In [85]:
printfuture = future.select(['futureNP', 'futureDem', 'futureGOP'])
printfuture.print_table()


|-----------------------+----------------------+-----------------------|
|              futureNP |            futureDem |            futureGOP  |
|-----------------------+----------------------+-----------------------|
|  339,788.401958366... | 297,350.726469258... | 583,439.493192371...  |
|-----------------------+----------------------+-----------------------|

Let's compute percent change from 2010 to 2014


In [17]:
changes0014 = parties.compute([
        ('total_change', agate.PercentChange('Total2000', 'Total2014')),
        ('nonparty_change', agate.PercentChange('NP2000', 'NP2014')),
        ('gopparty_change', agate.PercentChange('GOP2000', 'GOP2014')),
        ('demparty_change', agate.PercentChange('Dem2000', 'Dem2014')),
    ])

Lets round those values to one decimal place


In [18]:
from decimal import Decimal

def round_total_change(row):
    return row['total_change'].quantize(Decimal('0.1'))

def round_nonparty_change(row):
    return row['nonparty_change'].quantize(Decimal('0.1'))

def round_gopparty_change(row):
    return row['gopparty_change'].quantize(Decimal('0.1'))

def round_demparty_change(row):
    return row['demparty_change'].quantize(Decimal('0.1'))

rounded_changes = changes0014.compute([
    ('total_change_round', agate.Formula(agate.Number(), round_total_change)),
    ('nonparty_change_round', agate.Formula(agate.Number(), round_nonparty_change)),
    ('gopparty_change_round', agate.Formula(agate.Number(), round_gopparty_change)),
    ('demparty_change_round', agate.Formula(agate.Number(), round_demparty_change)),
])

Ugh it's ugly lets see only the fields we need


In [19]:
for_printing = rounded_changes.select(['County Name', 'total_change_round', 'nonparty_change_round', 'gopparty_change_round', 'demparty_change_round'])

Sort the table so largest growing to smallest


In [20]:
sorted_change = for_printing.order_by('nonparty_change_round', reverse=True)

Print top 50 highest growing populations


In [21]:
sorted_change.print_table()


|---------------+--------------------+-----------------------+-----------------------+------------------------|
|  County Name  | total_change_round | nonparty_change_round | gopparty_change_round | demparty_change_round  |
|---------------+--------------------+-----------------------+-----------------------+------------------------|
|  MCPHERSON    |               -7.0 |                 228.6 |                  -2.4 |                 -41.8  |
|  SARPY        |               42.6 |                 107.8 |                  34.9 |                  17.4  |
|  HOOKER       |               -8.4 |                  82.8 |                 -10.7 |                 -21.6  |
|  KIMBALL      |                7.2 |                  81.6 |                   6.6 |                 -23.7  |
|  THURSTON     |               10.8 |                  75.8 |                  -9.1 |                  12.2  |
|  HAYES        |               -6.7 |                  72.3 |                  -4.7 |                 -39.1  |
|  THOMAS       |              -16.2 |                  67.7 |                 -11.6 |                 -54.5  |
|  DOUGLAS      |               13.9 |                  66.4 |                   2.3 |                   4.5  |
|  PIERCE       |               -4.3 |                  66.1 |                   1.4 |                 -40.5  |
|  CHEYENNE     |                3.7 |                  66.0 |                   5.1 |                 -28.4  |
|  DAWSON       |                7.4 |                  63.2 |                   2.2 |                  -5.2  |
|  LANCASTER    |               15.5 |                  58.4 |                  10.2 |                   3.3  |
|  GREELEY      |              -13.9 |                  56.7 |                  -9.5 |                 -22.6  |
|  DAKOTA       |               13.8 |                  55.8 |                  -0.7 |                   8.9  |
|  CHERRY       |               -3.5 |                  54.2 |                   2.6 |                 -38.7  |
|  Total State  |                6.8 |                  54.1 |                   4.0 |                  -8.8  |
|  THAYER       |               -8.7 |                  54.0 |                  -4.5 |                 -33.8  |
|  HARLAN       |               -6.6 |                  53.4 |                   0.2 |                 -33.5  |
|  OTOE         |               -0.2 |                  52.9 |                  -2.8 |                 -18.8  |
|  DUNDY        |               -9.9 |                  52.4 |                  -3.3 |                 -48.8  |
|  WASHINGTON   |                9.6 |                  51.3 |                   8.1 |                  -9.8  |
|  HITCHCOCK    |               -5.8 |                  50.9 |                  -0.9 |                 -37.1  |
|  DAWES        |                6.4 |                  50.0 |                   0.9 |                  -5.4  |
|  SAUNDERS     |                5.4 |                  49.9 |                  24.5 |                 -27.9  |
|  ANTELOPE     |               -4.7 |                  46.2 |                   4.5 |                 -36.5  |
|  LINCOLN      |               -1.4 |                  45.8 |                   6.9 |                 -28.5  |
|  LOGAN        |               -1.9 |                  45.2 |                  -3.5 |                 -17.2  |
|  CUMING       |              -12.4 |                  44.7 |                 -12.8 |                 -29.6  |
|  GARFIELD     |               -9.8 |                  44.4 |                  -6.7 |                 -33.1  |
|  DODGE        |                0.0 |                  44.2 |                  -1.0 |                 -17.0  |
|  SALINE       |               -6.6 |                  43.3 |                  -0.3 |                 -22.5  |
|  MADISON      |               -1.0 |                  43.0 |                  -4.3 |                 -14.3  |
|  NANCE        |              -10.2 |                  42.6 |                   4.8 |                 -34.0  |
|  SCOTTS BLUFF |                1.5 |                  42.4 |                   2.1 |                 -18.4  |
|  PLATTE       |                0.7 |                  42.3 |                  10.6 |                 -27.8  |
|  HOWARD       |               -4.7 |                  41.6 |                   5.8 |                 -27.2  |
|  CASS         |                3.2 |                  40.7 |                   5.5 |                 -18.5  |
|  BUFFALO      |                4.9 |                  40.5 |                   8.0 |                 -19.8  |
|  CEDAR        |               -5.3 |                  40.4 |                  19.5 |                 -39.4  |
|  YORK         |               -3.4 |                  39.8 |                  -3.9 |                 -22.0  |
|  STANTON      |               -8.9 |                  39.3 |                 -12.8 |                 -18.0  |
|  FRONTIER     |               -8.7 |                  36.9 |                  -8.2 |                 -27.9  |
|  BLAINE       |              -13.2 |                  36.4 |                 -10.2 |                 -40.8  |
|  HALL         |                1.9 |                  35.8 |                  -0.3 |                 -11.2  |
|  FRANKLIN     |              -12.0 |                  35.6 |                  -8.6 |                 -34.4  |
|  SHERIDAN     |              -10.7 |                  35.4 |                 -10.7 |                 -31.0  |
|  NUCKOLLS     |              -15.2 |                  34.9 |                  -5.4 |                 -39.0  |
|  PAWNEE       |              -11.6 |                  34.2 |                  -3.3 |                 -34.9  |
|  NEMAHA       |              -10.1 |                  32.3 |                  -8.7 |                 -26.6  |
|  RICHARDSON   |              -11.7 |                  31.5 |                  -9.8 |                 -26.2  |
|  FILLMORE     |               -9.8 |                  31.0 |                  -4.5 |                 -30.5  |
|  KEITH        |                2.8 |                  31.0 |                   7.3 |                 -24.9  |
|  CHASE        |              -11.3 |                  30.8 |                   1.5 |                 -50.4  |
|  ADAMS        |               -3.4 |                  29.3 |                  -1.4 |                 -20.4  |
|  COLFAX       |               -8.5 |                  29.2 |                  -7.4 |                 -17.4  |
|  HAMILTON     |                0.4 |                  28.3 |                   4.7 |                 -23.0  |
|  SEWARD       |                1.5 |                  27.0 |                  10.8 |                 -22.2  |
|  CUSTER       |               -8.3 |                  26.8 |                  -5.3 |                 -30.5  |
|  MERRICK      |              -14.2 |                  26.2 |                  -7.8 |                 -38.9  |
|  KNOX         |               -6.7 |                  26.1 |                   2.9 |                 -28.7  |
|  GRANT        |               -7.3 |                  25.0 |                  -1.0 |                 -45.7  |
|  JEFFERSON    |              -13.0 |                  24.1 |                 -12.7 |                 -27.1  |
|  BANNER       |               -6.5 |                  23.3 |                  -0.7 |                 -57.1  |
|  PHELPS       |              -12.4 |                  22.8 |                  -7.3 |                 -38.5  |
|  KEARNEY      |               -6.0 |                  22.4 |                   1.1 |                 -32.0  |
|  GAGE         |              -11.0 |                  20.6 |                  -8.9 |                 -26.4  |
|  KEYA PAHA    |              -20.0 |                  20.6 |                 -10.6 |                 -55.8  |
|  RED WILLOW   |               -9.5 |                  20.4 |                  -3.3 |                 -38.8  |
|  GOSPER       |               -3.6 |                  19.4 |                   7.5 |                 -37.2  |
|  BURT         |              -13.9 |                  17.0 |                 -14.7 |                 -24.5  |
|  WHEELER      |                6.7 |                  14.9 |                  27.2 |                 -32.4  |
|  MORRILL      |              -12.1 |                  14.1 |                  -9.3 |                 -33.4  |
|  POLK         |              -10.9 |                  12.7 |                  -3.3 |                 -34.2  |
|  DEUEL        |               -2.3 |                  12.6 |                   1.2 |                 -27.7  |
|  CLAY         |              -13.2 |                  11.8 |                  -7.2 |                 -36.3  |
|  FURNAS       |              -16.7 |                  11.6 |                 -10.6 |                 -41.8  |
|  PERKINS      |              -10.2 |                  11.6 |                   4.2 |                 -45.9  |
|  VALLEY       |              -13.6 |                   9.5 |                  -9.0 |                 -28.3  |
|  WEBSTER      |              -13.0 |                   7.9 |                  -5.4 |                 -33.2  |
|  JOHNSON      |              -20.3 |                   4.5 |                 -10.5 |                 -38.8  |
|  DIXON        |               -9.1 |                   2.7 |                   4.7 |                 -33.5  |
|  BOX BUTTE    |              -17.7 |                   2.2 |                 -11.3 |                 -36.3  |
|  BOONE        |               -8.8 |                   1.8 |                   1.6 |                 -28.9  |
|  ROCK         |              -13.3 |                   0.0 |                  -5.4 |                 -46.4  |
|  GARDEN       |              -15.6 |                  -1.3 |                 -14.0 |                 -29.5  |
|  BOYD         |              -22.0 |                  -3.0 |                 -11.2 |                 -50.7  |
|  SHERMAN      |              -17.0 |                  -3.3 |                  -3.6 |                 -29.7  |
|  BUTLER       |              -10.5 |                  -4.3 |                  21.9 |                 -39.9  |
|  LOUP         |               -1.7 |                  -6.2 |                  14.6 |                 -49.6  |
|  HOLT         |              -14.2 |                  -7.6 |                  -1.8 |                 -45.4  |
|  BROWN        |              -12.0 |                 -13.8 |                  -5.4 |                 -35.9  |
|  SIOUX        |              -15.6 |                 -16.0 |                  -7.0 |                 -48.8  |
|  WAYNE        |              -20.8 |                 -19.7 |                 -14.3 |                 -37.0  |
|  ARTHUR       |               -2.4 |                 -35.3 |                   9.2 |                 -36.9  |
|---------------+--------------------+-----------------------+-----------------------+------------------------|

In [23]:
sorted_change.to_csv('neb-county-political.csv')