Baltimore Parking/Traffic Citations

This dataset (Baltimore_Parking_Tickets_2015-01-21.csv) downloaded Jan. 21, 2015 approx. 8:30pm.

The dataset on data.baltimorecity.gov is for 2 years rolling, but also contains any records from more than 2 years prior with an outstanding balance. In order to make valid comparisons and metrics, we can only look at the last 2 years since we have all records during that time. This is done after the section header "Last 2 Years of Data."

In [173]:
import pandas as pd
import numpy
import plotly.plotly as py
from plotly.graph_objs import *

red_orange = '#FF3300'
light_cyan = '#00CCFF'
gray_light = '#bbbbbb'
In [2]:
# takes very long time!
df = pd.read_csv('raw_data/Baltimore_Parking_Citations_2015-03-06.csv',index_col='citation', parse_dates=[10], infer_datetime_format=True)
/Users/Justin/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pandas/io/parsers.py:1159: DtypeWarning:

Columns (2) have mixed types. Specify dtype option on import or set low_memory=False.

In [3]:
df['violFine_parsed'] = df['violFine'].str.replace("$","").apply(lambda x: float(x))
df['openFine_parsed'] = df['openFine'].str.replace("$","").apply(lambda x: float(x))
df['openPenalty_parsed'] = df['openPenalty'].str.replace("$","").apply(lambda x: float(x))
df['balance_parsed'] = df['balance'].str.replace("$","").apply(lambda x: float(x))
In [4]:
len(df)
Out[4]:
1049837
In [5]:
df.head()
Out[5]:
tag expmm expyy make state location violCode Description violFine violDate balance penaltyDate openFine openPenalty noticeDate ImportDate violFine_parsed openFine_parsed openPenalty_parsed balance_parsed
citation
91919465 XNY3041 7 15 DODGE VA 800 FAYETTE ST 11 Residential Parking Permit Only $52.00 2015-01-20 14:08:00 $52.00 NaN $52.00 $0.00 NaN 01/21/2015 12:02:00 PM +0000 52 52 0 52
91919457 1BL8490 4 16 HONDA MD 800 FAYETTE ST 11 Residential Parking Permit Only $52.00 2015-01-20 14:06:00 $52.00 NaN $52.00 $0.00 NaN 01/21/2015 12:02:00 PM +0000 52 52 0 52
91919440 CAKZ79 12 15 FORD FL 800 FAYETTE ST 11 Residential Parking Permit Only $52.00 2015-01-20 14:05:00 $52.00 NaN $52.00 $0.00 NaN 01/21/2015 12:02:00 PM +0000 52 52 0 52
91919432 7BG2327 2 16 CHRYS MD 700 FAYETTE ST 11 Residential Parking Permit Only $52.00 2015-01-20 14:01:00 $52.00 NaN $52.00 $0.00 NaN 01/21/2015 12:02:00 PM +0000 52 52 0 52
91919424 13842388 2 15 INFIN GA 300 FREMONT AVE 11 Residential Parking Permit Only $52.00 2015-01-20 13:55:00 $52.00 NaN $52.00 $0.00 NaN 01/21/2015 12:02:00 PM +0000 52 52 0 52

By Citation Type (Full Dataset)

In [6]:
groupby_desc = df.groupby('Description')

citation_desc = pd.DataFrame()

# Total fines for each citation type
citation_desc['fines'] = groupby_desc['violFine_parsed'].sum()

# Number of unique locations each citation type was issued at
citation_desc['unique_locs'] = groupby_desc['location'].nunique()

# Fine type concentration by location
citation_desc['fine_conc_loc'] = (citation_desc['fines'] / citation_desc['unique_locs']).apply(lambda x: round(x,2))

citation_desc.sort('fines',inplace=True,ascending=False)

citation_desc['first_date'] = ''
citation_desc['last_date'] = ''
for row in citation_desc.index:
    # First issue date for each citation type
    citation_desc['first_date'].ix[row] = min(groupby_desc['violDate'].get_group(row))
    # Last issue date for each citation type
    citation_desc['last_date'].ix[row] = max(groupby_desc['violDate'].get_group(row))
# Total date range in years for each citation type
citation_desc['date_range_years'] = (citation_desc['last_date'] - citation_desc['first_date']).astype('timedelta64[D]')/365. 
# Fines per year for each citation type
citation_desc['fines_annual'] = citation_desc['fines']/citation_desc['date_range_years']

citation_desc.head()
#citation_desc.to_csv('citation_desc_date_range_new.csv')
/Users/Justin/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pandas/core/indexing.py:121: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  self._setitem_with_indexer(indexer, value)
Out[6]:
fines unique_locs fine_conc_loc first_date last_date date_range_years fines_annual
Description
Red Light Violation 6708000 162 41407.41 2002-11-08 12:27:00 2013-04-01 21:23:00 10.402740 644830.129049
All Other Parking Meter Violations 6637646 8012 828.46 2004-06-12 10:44:00 2015-01-20 13:45:00 10.613699 625384.819308
Fixed Speed Camera 5773840 91 63448.79 2009-11-02 09:30:00 2012-12-31 14:09:00 3.164384 1824633.419913
No Stop/Park Street Cleaning 4840482 9501 509.47 2004-09-30 09:02:00 2015-01-20 13:36:00 10.312329 469387.866631
No Stopping/Standing Tow Away Zone 3251300 6912 470.38 2004-10-23 17:15:00 2015-01-20 13:50:00 10.246575 317306.016043

Time Series

In [6]:
# takes a long time!
df_time = df.fillna(0).set_index(df['violDate'])
# takes a long time!
df_time['ImportDate_parsed'] = pd.to_datetime(df_time['ImportDate'])
df_time.sort(inplace=True)
df_time.head()
Out[6]:
tag expmm expyy make state location violCode Description violFine violDate ... penaltyDate openFine openPenalty noticeDate ImportDate violFine_parsed openFine_parsed openPenalty_parsed balance_parsed ImportDate_parsed
violDate
2002-11-08 12:27:00 KZW022 09 4 TOYOT MD PARK HGTS @ VIOLET AVE. 30 Red Light Violation $75.00 2002-11-08 12:27:00 ... 0 $75.00 $0.00 12/16/2002 05/07/2013 05:41:00 PM +0000 75 75 0 75 2013-05-07 17:41:00
2004-01-15 19:50:00 LCK831 01 6 CHEV MD EDMONDSON @ ATHOL / WOODRIDGE 30 Red Light Violation $75.00 2004-01-15 19:50:00 ... 0 $75.00 $0.00 02/24/2004 05/07/2013 05:41:00 PM +0000 75 75 0 75 2013-05-07 17:41:00
2004-02-29 14:12:00 LSN017 08 5 OTHER MD RUSSELL (NB) @ HAMBURG ST. 30 Red Light Violation $75.00 2004-02-29 14:12:00 ... 0 $25.00 $25.00 04/29/2004 05/07/2013 05:41:00 PM +0000 75 25 25 50 2013-05-07 17:41:00
2004-03-04 19:03:00 MGC390 01 6 OTHER MD NORTHERN PARKWAY @ FALLS RD. 30 Red Light Violation $75.00 2004-03-04 19:03:00 ... 0 $75.00 $0.00 04/29/2004 05/07/2013 05:41:00 PM +0000 75 75 0 75 2013-05-07 17:41:00
2004-03-31 12:16:00 MLG502 02 6 0 MD FRANKLIN ST. @ CATHEDRAL STREE 30 Red Light Violation $75.00 2004-03-31 12:16:00 ... 0 $75.00 $25.00 06/14/2004 05/07/2013 05:41:00 PM +0000 75 75 25 100 2013-05-07 17:41:00

5 rows × 21 columns

In [173]:
# Monthly totals for all citations
df_time['violFine'].resample('M',how='count').plot()
Out[173]:
<matplotlib.axes._subplots.AxesSubplot at 0x1b53a68d0>
In [24]:
# Plot top 10 infraction types over time

fig = plt.figure(figsize=[10,8])
for key in citation_desc[:10].index:
    #print key
    df_time['violFine_parsed'][df_time['Description']==key].resample('M', how='count').plot(label=key,grid='off')

xlabel('')
ylabel('Number of Citations')
legend(loc='upper left')

#fig.savefig('Top 10 Monthly Citation Plot 2015-01-21.png', bbox_tight='inches')
Out[24]:
<matplotlib.legend.Legend at 0x11b995a50>
In [124]:
# Monthly mobile speed cameras
df_time['violCode'][df_time['Description']=='Mobile Speed Camera'].resample('M',how='count').plot()
Out[124]:
<matplotlib.axes._subplots.AxesSubplot at 0x112fa6e90>
In [50]:
# Total value of fines issued in database before January 21, 2013
df_time['violFine_parsed'][df_time.index <= pd.to_datetime('21-jan-2013')].sum()
Out[50]:
23873386.0
In [47]:
df_time[(df_time.index <= pd.to_datetime('21-jan-2013')) & (df_time['balance_parsed']==0)]
Out[47]:
tag expmm expyy make state location violCode Description violFine violDate ... penaltyDate openFine openPenalty noticeDate ImportDate violFine_parsed openFine_parsed openPenalty_parsed balance_parsed ImportDate_parsed
violDate
2012-09-11 11:28:00 7AP9379 05 13 HOND MD 2600 BLOCK OF GWYNNS FALLS PKW 32 Fixed Speed Camera $40.00 2012-09-11 11:28:00 ... 0 $0.00 $0.00 10/15/2012 05/07/2013 05:41:00 PM +0000 40 0 0 0 2013-05-07 17:41:00
2012-08-19 16:27:00 HWA3647 02 2 HYUND PA PULASKI EB @ NORTH POINT 30 Red Light Violation $75.00 2012-08-19 16:27:00 ... 0 $0.00 $0.00 01/28/2013 05/07/2013 05:41:00 PM +0000 75 0 0 0 2013-05-07 17:41:00
2012-08-18 12:02:00 01T683 10 14 FORD MD NORTHERN PKWY @ SPRINGLAKE WB 30 Red Light Violation $75.00 2012-08-18 12:02:00 ... 0 $0.00 $0.00 09/26/2012 06/26/2014 11:01:00 AM +0000 75 0 0 0 2014-06-26 11:01:00
2012-04-22 18:40:00 8GAL75 04 14 SUZI MD EDMONSON AVE EB @ HILTON ST 30 Red Light Violation $75.00 2012-04-22 18:40:00 ... 0 $0.00 $0.00 08/28/2012 05/07/2013 05:41:00 PM +0000 75 0 0 0 2013-05-07 17:41:00
2012-03-27 21:29:00 HLN4766 06 12 CHEV PA 4100 HILLEN RD 12 No Stopping/Standing Not Tow-Away Zone $32.00 2012-03-27 21:29:00 ... 0 $0.00 $0.00 0 05/07/2013 05:41:00 PM +0000 32 0 0 0 2013-05-07 17:41:00
2011-12-29 13:03:00 1AD9902 11 12 HYUN MD 1600 FLEET ST 18 All Other Parking Meter Violations $32.00 2011-12-29 13:03:00 ... 0 $0.00 $0.00 0 05/07/2013 05:41:00 PM +0000 32 0 0 0 2013-05-07 17:41:00
2011-12-18 16:34:00 DY1893 10 12 ISU DC MLK BLVD NB @ WASHINGTON BLVD 30 Red Light Violation $75.00 2011-12-18 16:34:00 ... 0 $0.00 $0.00 02/03/2012 05/07/2013 05:41:00 PM +0000 75 0 0 0 2013-05-07 17:41:00
2011-11-12 22:54:00 JH1919 04 15 MERZ MD NORTH AVE WB @ HOWARD ST 30 Red Light Violation $75.00 2011-11-12 22:54:00 ... 0 $0.00 $0.00 12/14/2011 12/27/2013 12:02:00 PM +0000 75 0 0 0 2013-12-27 12:02:00
2011-10-31 16:45:00 8GAL75 04 14 SUZI MD PRESIDENT ST SB @ FAYETTE ST 30 Red Light Violation $75.00 2011-10-31 16:45:00 ... 0 $0.00 $0.00 08/28/2012 05/07/2013 05:41:00 PM +0000 75 0 0 0 2013-05-07 17:41:00
2011-08-26 09:17:00 1DCN13 02 12 FORD MD 3900 BENZINGER ROAD 5 Obstruct/Impeding Movement of Pedestrian $77.00 2011-08-26 09:17:00 ... 0 $0.00 $0.00 04/18/2012 05/07/2013 05:41:00 PM +0000 77 0 0 0 2013-05-07 17:41:00
2011-04-26 10:51:00 27933M5 12 15 PONT MD 7000 REISTERSTOWN RD. S/B 32 Fixed Speed Camera $40.00 2011-04-26 10:51:00 ... 0 $0.00 $0.00 05/25/2011 08/28/2014 11:03:00 AM +0000 40 0 0 0 2014-08-28 11:03:00
2011-04-19 18:19:00 4AE3717 01 13 HOND MD 6114 HARFORD ROAD N/B 32 Fixed Speed Camera $40.00 2011-04-19 18:19:00 ... 0 $0.00 $0.00 05/19/2011 05/07/2013 05:41:00 PM +0000 40 0 0 0 2013-05-07 17:41:00
2010-06-13 19:26:00 ECH4208 06 10 TOYT OH PULASKI EB @ NORTH POINT 30 Red Light Violation $75.00 2010-06-13 19:26:00 ... 0 $0.00 $0.00 11/01/2010 01/28/2014 12:02:00 PM +0000 75 0 0 0 2014-01-28 12:02:00
2009-09-04 17:45:00 HPF210 04 16 KIA MD COLD SPRING WB @ LOCH RAVEN 30 Red Light Violation $75.00 2009-09-04 17:45:00 ... 0 $0.00 $0.00 10/21/2009 12/26/2014 12:02:00 PM +0000 75 0 0 0 2014-12-26 12:02:00
2008-12-04 20:55:00 DRSMITH 05 13 FORD MD PULASKI EB @ NORTH POINT 30 Red Light Violation $75.00 2008-12-04 20:55:00 ... 0 $0.00 $0.00 06/23/2010 06/06/2013 11:02:00 AM +0000 75 0 0 0 2013-06-06 11:02:00
2008-07-27 19:44:00 3BCD91 10 9 BUIC MD REISTERTOWN SB @ DRUID PARK 30 Red Light Violation $75.00 2008-07-27 19:44:00 ... 0 $0.00 $0.00 08/20/2008 05/07/2013 05:41:00 PM +0000 75 0 0 0 2013-05-07 17:41:00

16 rows × 21 columns

In [36]:
df_time[(df_time['ImportDate_parsed'] <= pd.to_datetime('21-jan-2013')) & (df_time['balance_parsed']==0)]
Out[36]:
tag expmm expyy make state location violCode Description violFine violDate ... penaltyDate openFine openPenalty noticeDate ImportDate violFine_parsed openFine_parsed openPenalty_parsed balance_parsed ImportDate_parsed
violDate

0 rows × 21 columns

In [86]:
df_time_rec = df_time.ix['21-jan-2013':'21-jan-2015']
In [55]:
total_balance = df_time['balance_parsed'].sum()
total_fines = df_time['violFine_parsed'].ix['21-jan-2013':'21-jan-2015'].sum()
total_pen = df_time['openPenalty_parsed'].ix['21-jan-2013':'21-jan-2015'].sum()
In [56]:
print total_balance, total_fines, total_pen
122457404.0 24098830.0 12539524.0
In [50]:
total_fines+total_pen
Out[50]:
36638354.0
In [51]:
(total_fines+total_pen)/total_balance
Out[51]:
1.8252984377453603
In [52]:
total_pen/total_balance
Out[52]:
0.62471074894004386
In [68]:
df_time['balance_parsed'][df_time['balance_parsed']==0].count()
Out[68]:
357489
In [75]:
df_time['openFine_parsed'].sum()+df_time['openPenalty_parsed'].sum()
Out[75]:
122410001.0
In [89]:
df_time['balance_parsed'].sum()
Out[89]:
122457404.0
In [80]:
df_time['violFine_parsed'].sum()
Out[80]:
47972216.0
In [81]:
df_time['openPenalty_parsed'].sum()
Out[81]:
91106158.0
In [82]:
df_time['balance_parsed'].sum() - (df_time['openFine_parsed'].sum()+df_time['openPenalty_parsed'].sum())
Out[82]:
47403.0
In [84]:
df_time['violFine_parsed'][df_time['balance_parsed']==0].sum()
Out[84]:
16541671.0
In [88]:
df_time['balance_parsed'].ix['21-jan-2013':'21-jan-2015'].sum()
Out[88]:
20072528.0
In [90]:
df_time['violFine_parsed'].ix['21-jan-2013':'21-jan-2015'].sum()
Out[90]:
24098830.0
In [92]:
df_time['openPenalty_parsed'].ix['21-jan-2013':'21-jan-2015'].sum()
Out[92]:
12539524.0
In [93]:
df_time['openFine_parsed'].ix['21-jan-2013':'21-jan-2015'].sum()
Out[93]:
7526763.0
In [94]:
df_time['openPenalty_parsed'].ix['21-jan-2013':'21-jan-2015'].sum()+df_time['openFine_parsed'].ix['21-jan-2013':'21-jan-2015'].sum()
Out[94]:
20066287.0
In [95]:
df_time['balance_parsed'].ix[:'20-jan-2013'].sum()
Out[95]:
102384876.0
In [96]:
df_time['violFine_parsed'].ix[:'20-jan-2013'].sum()
Out[96]:
23873386.0
In [98]:
df_time['balance_parsed'].ix[:'20-jan-2013'].sum()/df_time['violFine_parsed'].ix[:'20-jan-2013'].sum()
Out[98]:
4.2886616921453875

Last 2 Years of Data

Everything that follows is using only the most recent 2 years worth of data since all records are kept on a 2 year rolling basis.

In [9]:
df_time_2 = df_time.ix['01-feb-2013':'28-feb-2015']
df_time_2['violFine_parsed'].resample('M',how='count').plot()
Out[9]:
<matplotlib.axes._subplots.AxesSubplot at 0x112f8bf50>
In [11]:
groupby_desc2 = df_time_2.groupby('Description')

citation_desc2 = pd.DataFrame()

# Total fines for each citation type
citation_desc2['fines'] = groupby_desc2['violFine_parsed'].sum()

# Number of unique locations each citation type was issued at
citation_desc2['unique_locs'] = groupby_desc2['location'].nunique()

# Fine type concentration by location
citation_desc2['fine_conc_loc'] = (citation_desc2['fines'] / citation_desc2['unique_locs']).apply(lambda x: round(x,2))

citation_desc2.sort('fines',inplace=True,ascending=False)

citation_desc2['first_date'] = ''
citation_desc2['last_date'] = ''
for row in citation_desc2.index:
    # First issue date for each citation type
    citation_desc2['first_date'].ix[row] = min(groupby_desc2['violDate'].get_group(row))
    # Last issue date for each citation type
    citation_desc2['last_date'].ix[row] = max(groupby_desc2['violDate'].get_group(row))
# Total date range in years for each citation type
citation_desc2['date_range_years'] = (citation_desc2['last_date'] - citation_desc2['first_date']).astype('timedelta64[D]')/365. 
# Fines per year for each citation type
citation_desc2['fines_annual'] = citation_desc2['fines']/citation_desc2['date_range_years']

citation_desc2
#citation_desc.to_csv('citation_desc_date_range_new.csv')
/Users/Justin/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/pandas/core/indexing.py:121: SettingWithCopyWarning:


A value is trying to be set on a copy of a slice from a DataFrame

See the the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

Out[11]:
fines unique_locs fine_conc_loc first_date last_date date_range_years fines_annual
Description
All Other Parking Meter Violations 5985029 5470 1094.16 2013-02-01 09:25:00 2015-02-28 21:12:00 2.073973 2.885780e+06
No Stop/Park Street Cleaning 3379044 5043 670.05 2013-02-01 07:47:00 2015-02-24 12:00:00 2.063014 1.637916e+06
No Stopping/Standing Tow Away Zone 2902978 4766 609.10 2013-02-01 07:12:00 2015-02-28 21:19:00 2.073973 1.399719e+06
Residential Parking Permit Only 2169212 2029 1069.10 2013-02-01 13:09:00 2015-02-28 21:00:00 2.073973 1.045921e+06
No Stopping/Standing Not Tow-Away Zone 2087255 8459 246.75 2013-02-01 01:00:00 2015-02-28 22:26:00 2.073973 1.006404e+06
Expired Tags 1605454 14684 109.33 2013-02-01 04:05:00 2015-02-28 18:20:00 2.073973 7.740961e+05
No Stop/Park Handicap 1541932 1201 1283.87 2013-02-01 12:23:00 2015-02-28 18:47:00 2.073973 7.434679e+05
Obstruct/Impeding Movement of Pedestrian 967692 3687 262.46 2013-02-01 07:25:00 2015-02-28 22:15:00 2.073973 4.665886e+05
In Transit Zone/Stop 821673 1796 457.50 2013-02-01 09:16:00 2015-02-28 21:24:00 2.073973 3.961832e+05
All Other Stopping or Parking Violations 762406 6566 116.11 2013-02-01 04:33:00 2015-02-28 17:36:00 2.073973 3.676066e+05
No Stopping//Parking Stadium Event Camden 637296 474 1344.51 2013-03-03 15:30:00 2015-01-23 20:35:00 1.893151 3.366325e+05
Abandonded Vehicle 613220 1854 330.76 2013-02-01 09:49:00 2015-02-27 13:51:00 2.071233 2.960652e+05
Commercial Veh/Residence under 20,000 lbs 608328 1396 435.77 2013-02-04 21:10:00 2015-02-28 21:34:00 2.065753 2.944824e+05
Less Than 15 feet from Fire Hydrant 512799 2611 196.40 2013-02-01 03:00:00 2015-02-28 21:45:00 2.073973 2.472545e+05
Obstruct/Impeding Flow of Traffic 373840 2473 151.17 2013-02-01 09:01:00 2015-02-28 16:25:00 2.073973 1.802531e+05
Passenger Loading Zone 242587 992 244.54 2013-02-01 10:04:00 2015-02-28 18:31:00 2.073973 1.169673e+05
Mobile Speed Camera 219000 36 6083.33 2013-02-20 13:05:00 2013-04-02 19:10:00 0.112329 1.949634e+06
Commercial Veh/Residence over 20,000 lbs 209134 253 826.62 2013-03-04 19:30:00 2015-02-23 21:11:00 1.975342 1.058723e+05
Exceeding 48 Hours 128886 3197 40.31 2013-02-01 10:07:00 2015-02-27 13:42:00 2.071233 6.222671e+04
Fire Lane/Handicapped Violation 100083 615 162.74 2013-02-01 12:40:00 2015-02-22 23:45:00 2.057534 4.864220e+04
Red Light Violation 34125 61 559.43 2013-03-09 15:38:00 2013-04-01 21:23:00 0.063014 5.415489e+05
Blocking Garage or Driveway 20140 548 36.75 2013-02-02 00:55:00 2015-02-27 21:50:00 2.068493 9.736556e+03
Less 30’ from Intersection 4608 124 37.16 2013-02-05 16:56:00 2014-12-29 09:17:00 1.893151 2.434038e+03
Right on Red 3225 16 201.56 2013-03-27 15:31:00 2013-04-01 19:08:00 0.013699 2.354250e+05
No Stop/Stand/Park Cruising 3186 42 75.86 2013-02-01 23:52:00 2015-02-06 20:41:00 2.010959 1.584319e+03
In Taxicab Stand 2267 54 41.98 2013-02-07 12:00:00 2015-02-28 17:13:00 2.057534 1.101804e+03
No Stopping or No Parking Pimlico Event 1403 14 100.21 2013-03-08 11:03:00 2015-01-01 06:52:00 1.816438 7.723906e+02
Snow Emergency Route Violation 308 4 77.00 2014-02-02 07:00:00 2014-08-16 03:29:00 0.531507 5.794845e+02
Less 30? from Intersection 160 5 32.00 2015-01-20 11:27:00 2015-02-09 13:40:00 0.054795 2.920000e+03
No Stopping/Parking Stadium Event – 33rd 17 1 17.00 2013-07-07 01:43:00 2013-07-07 01:43:00 0.000000 inf
In [12]:
# Plot top 10 infraction types over time

fig = plt.figure(figsize=[10,8])
ax1 = plt.subplot(111)

for key in citation_desc2[:10].index:
    #print key
    df_time_2['violFine_parsed'][df_time_2['Description']==key].ix['01-feb-2013':'31-dec-2014'].resample('M', how='count').plot(linewidth=2,label=key,grid='off')

# turn off square border around plot
ax1.spines["top"].set_visible(False)  
ax1.spines["bottom"].set_visible(False)  
ax1.spines["right"].set_visible(False)  
ax1.spines["left"].set_visible(False)

# turn off ticks
ax1.tick_params(axis="both", which="both", bottom="off", top="off",
               labelbottom="on", left="off", right="off", labelleft="on",labelsize=14) 


xlabel('')
ylabel('Number of Citations', fontsize=14)
legend(loc='upper left', fontsize=12)
title('Top 10 Citation Types (by Total Fines)\n 01-Feb-2013 to 31-Dec-2014', fontsize=18)

#fig.savefig('output/Top 10 Monthly Citation Plot 2013-02-01 to 2014-12-31.png', bbox_tight='inches')
Out[12]:
<matplotlib.text.Text at 0x11214b3d0>

Last 2 Years by Location

In [179]:
groupby_loc = df_time_2.groupby(df_time_2['location'])

loc_counts = groupby_loc['Description'].count()
loc_revenue = groupby_loc['violFine_parsed'].sum()

loc_counts.sort(inplace=True, ascending=False)
loc_revenue.sort(inplace=True, ascending=False)
In [180]:
print '\nNumber of locations:', loc_revenue.count()
print 'Number of locations with fines issued greater than $10,000: ', loc_revenue[loc_revenue>=10000].count()
print '% of all locations with fines issued greater than $10,000:', round(100*float(loc_revenue[loc_revenue>=10000].count()) / float(loc_revenue.count()),1)
print '% Revenue generated by locations with fines issued greater than $10,000:', round(100*loc_revenue[loc_revenue>=10000].sum() / loc_revenue.sum(),1),'\n'


loc_revenue.hist(bins=50)
Number of locations: 38597
Number of locations with fines issued greater than $10,000:  447
% of all locations with fines issued greater than $10,000: 1.2
% Revenue generated by locations with fines issued greater than $10,000: 45.8 

Out[180]:
<matplotlib.axes._subplots.AxesSubplot at 0x1599c0f10>
In [15]:
loc_revenue[:20].to_csv('output/Top20_Target_locations.csv')
In [140]:
df_time_2[:-30]
Out[140]:
tag expmm expyy make state location violCode Description violFine violDate ... penaltyDate openFine openPenalty noticeDate ImportDate violFine_parsed openFine_parsed openPenalty_parsed balance_parsed ImportDate_parsed
violDate
2013-01-21 08:12:00 5AR6725 04 14 PONTI MD 3000 CHARLES ST 18 All Other Parking Meter Violations $32.00 2013-01-21 08:12:00 ... 0 $32.00 $325.00 02/20/2013 09/09/2014 11:02:00 AM +0000 32 32 325 357 2014-09-09 11:02:00
2013-01-21 08:16:00 2AV0600 07 14 HONDA MD 900 BONAPARTE AVE 12 No Stopping/Standing Not Tow-Away Zone $32.00 2013-01-21 08:16:00 ... 0 $32.00 $325.00 02/20/2013 09/09/2014 11:02:00 AM +0000 32 32 325 357 2014-09-09 11:02:00
2013-01-21 08:40:00 4AS1217 05 14 ACURA MD 100 CLINTON ST 20 Passenger Loading Zone $32.00 2013-01-21 08:40:00 ... 0 $32.00 $300.00 02/20/2013 09/09/2014 11:02:00 AM +0000 32 32 300 332 2014-09-09 11:02:00
2013-01-21 08:46:00 6AY6243 12 14 NISSA MD 3400 BANK ST 18 All Other Parking Meter Violations $32.00 2013-01-21 08:46:00 ... 0 $32.00 $325.00 02/20/2013 10/25/2014 11:02:00 AM +0000 32 32 325 357 2014-10-25 11:02:00
2013-01-21 08:55:00 3AY2738 02 13 OLDSM MD 400 CONKLING ST 18 All Other Parking Meter Violations $32.00 2013-01-21 08:55:00 ... 0 $32.00 $300.00 02/20/2013 09/09/2014 11:02:00 AM +0000 32 32 300 332 2014-09-09 11:02:00
2013-01-21 09:17:00 899M381 04 15 OLDSM MD 400 REDWOOD ST 18 All Other Parking Meter Violations $32.00 2013-01-21 09:17:00 ... 0 $32.00 $300.00 02/20/2013 09/09/2014 11:02:00 AM +0000 32 32 300 332 2014-09-09 11:02:00
2013-01-21 09:27:00 HPM8797 07 13 HONDA PA 300 REDWOOD ST 18 All Other Parking Meter Violations $32.00 2013-01-21 09:27:00 ... 0 $32.00 $300.00 07/01/2013 01/09/2015 12:02:00 PM +0000 32 32 300 332 2015-01-09 12:02:00
2013-01-21 09:34:00 AGY1571 01 14 NISSA GA 900 SAINT PAUL ST 18 All Other Parking Meter Violations $32.00 2013-01-21 09:34:00 ... 0 $32.00 $0.00 0 05/07/2013 05:41:00 PM +0000 32 32 0 32 2013-05-07 17:41:00
2013-01-21 10:05:00 HPB535 06 13 CHEVR MD 500 WOLFE ST 18 All Other Parking Meter Violations $32.00 2013-01-21 10:05:00 ... 0 $32.00 $325.00 02/20/2013 09/09/2014 11:02:00 AM +0000 32 32 325 357 2014-09-09 11:02:00
2013-01-21 10:15:00 6AV2518 08 14 TOYOT MD 00 BIDDLE ST 18 All Other Parking Meter Violations $32.00 2013-01-21 10:15:00 ... 0 $32.00 $300.00 02/20/2013 09/09/2014 11:02:00 AM +0000 32 32 300 332 2014-09-09 11:02:00
2013-01-21 10:21:00 26185M2 08 15 GMC MD 1500 LAKEVIEW AVE 22 Expired Tags $32.00 2013-01-21 10:21:00 ... 0 $32.00 $300.00 02/20/2013 09/09/2014 11:02:00 AM +0000 32 32 300 332 2014-09-09 11:02:00
2013-01-21 10:35:00 4AW4641 12 12 NISSA MD 1900 VINE ST 22 Expired Tags $32.00 2013-01-21 10:35:00 ... 0 $32.00 $300.00 02/20/2013 09/09/2014 11:02:00 AM +0000 32 32 300 332 2014-09-09 11:02:00
2013-01-21 10:41:00 6AX7862 12 12 CADIL MD 1900 FAIRMOUNT AVE 22 Expired Tags $32.00 2013-01-21 10:41:00 ... 0 $32.00 $300.00 02/20/2013 09/09/2014 11:02:00 AM +0000 32 32 300 332 2014-09-09 11:02:00
2013-01-21 10:54:00 20348HT 02 14 FORD MD 2800 HOMEWOOD AVE 12 No Stopping/Standing Not Tow-Away Zone $32.00 2013-01-21 10:54:00 ... 0 $0.00 $0.00 02/20/2013 03/08/2014 12:03:00 PM +0000 32 0 0 0 2014-03-08 12:03:00
2013-01-21 11:32:00 7FWY40 06 14 TOYOT MD 1800 EASTERN AVE 18 All Other Parking Meter Violations $32.00 2013-01-21 11:32:00 ... 0 $32.00 $300.00 02/20/2013 09/09/2014 11:02:00 AM +0000 32 32 300 332 2014-09-09 11:02:00
2013-01-21 11:41:00 T657590 03 13 CHEVR MD 700 EDEN ST 18 All Other Parking Meter Violations $32.00 2013-01-21 11:41:00 ... 0 $32.00 $0.00 0 05/07/2013 05:41:00 PM +0000 32 32 0 32 2013-05-07 17:41:00
2013-01-21 11:48:00 YRK9625 06 13 FORD PA 700 EDEN ST 12 No Stopping/Standing Not Tow-Away Zone $32.00 2013-01-21 11:48:00 ... 0 $32.00 $300.00 07/01/2013 01/09/2015 12:02:00 PM +0000 32 32 300 332 2015-01-09 12:02:00
2013-01-21 11:48:00 19248979 01 13 HONDA NC 1800 EASTERN AVE 18 All Other Parking Meter Violations $32.00 2013-01-21 11:48:00 ... 0 $32.00 $0.00 0 05/07/2013 05:41:00 PM +0000 32 32 0 32 2013-05-07 17:41:00
2013-01-21 12:01:00 1AT655 08 8 CHEVR MD 800 LIGHT ST 18 All Other Parking Meter Violations $32.00 2013-01-21 12:01:00 ... 0 $0.00 $0.00 02/20/2013 06/27/2013 11:03:00 AM +0000 32 0 0 0 2013-06-27 11:03:00
2013-01-21 12:01:00 1A1655 11 14 CHEV MD E/S 800 LIGHT 18 All Other Parking Meter Violations $32.00 2013-01-21 12:01:00 ... 0 $0.00 $0.00 0 06/28/2013 11:02:00 AM +0000 32 0 0 0 2013-06-28 11:02:00
2013-01-21 12:02:00 4AW1092 12 12 FORD MD 2600 HAFER ST 22 Expired Tags $32.00 2013-01-21 12:02:00 ... 0 $32.00 $300.00 02/20/2013 09/09/2014 11:02:00 AM +0000 32 32 300 332 2014-09-09 11:02:00
2013-01-21 12:14:00 AEV439 09 13 CHEVR SC 900 SAINT PAUL ST 11 Residential Parking Permit Only $52.00 2013-01-21 12:14:00 ... 0 $0.00 $0.00 0 05/25/2013 11:03:00 AM +0000 52 0 0 0 2013-05-25 11:03:00
2013-01-21 12:25:00 3AW9896 10 12 FORD MD 0 EUTAW ST 20 Passenger Loading Zone $32.00 2013-01-21 12:25:00 ... 0 $0.00 $0.00 02/20/2013 03/13/2014 11:02:00 AM +0000 32 0 0 0 2014-03-13 11:02:00
2013-01-21 12:31:00 1AV8519 07 14 HYUN MD 5100 PARK HTS 19 Exceeding 48 Hours $32.00 2013-01-21 12:31:00 ... 0 $32.00 $325.00 02/20/2013 09/09/2014 11:02:00 AM +0000 32 32 325 357 2014-09-09 11:02:00
2013-01-21 12:38:00 6CSF67 02 12 MERCU MD 300 MARTINGALE AVE 99 All Other Stopping or Parking Violations $32.00 2013-01-21 12:38:00 ... 0 $32.00 $300.00 02/20/2013 09/09/2014 11:02:00 AM +0000 32 32 300 332 2014-09-09 11:02:00
2013-01-21 13:11:00 6AX6004 10 14 DODGE MD 1800 FLEET ST 12 No Stopping/Standing Not Tow-Away Zone $32.00 2013-01-21 13:11:00 ... 0 $32.00 $325.00 02/20/2013 09/09/2014 11:02:00 AM +0000 32 32 325 357 2014-09-09 11:02:00
2013-01-21 13:33:00 NMR470 03 12 TOYOT WV 600 EDEN ST 20 Passenger Loading Zone $32.00 2013-01-21 13:33:00 ... 0 $32.00 $0.00 0 05/07/2013 05:41:00 PM +0000 32 32 0 32 2013-05-07 17:41:00
2013-01-21 14:08:00 7AL2128 10 13 CHEV MD 2401 BELAIR RD 26 No Stop/Park Handicap $502.00 2013-01-21 14:08:00 ... 0 $0.00 $0.00 02/20/2013 10/01/2013 11:05:00 AM +0000 502 0 0 0 2013-10-01 11:05:00
2013-01-21 15:42:00 60P869 08 14 CINT MD E/S 3200 GREENMOUNT 22 Expired Tags $32.00 2013-01-21 15:42:00 ... 0 $0.00 $0.00 10/30/2013 09/10/2014 11:03:00 AM +0000 32 0 0 0 2014-09-10 11:03:00
2013-01-21 17:15:00 M040048 11 14 GMC MD 600 PRESIDENT ST 12 No Stopping/Standing Not Tow-Away Zone $32.00 2013-01-21 17:15:00 ... 0 $32.00 $0.00 0 05/07/2013 05:41:00 PM +0000 32 32 0 32 2013-05-07 17:41:00
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
2015-01-20 12:45:00 94423CC 9 15 HONDA MD 600 PACA ST 11 Residential Parking Permit Only $52.00 2015-01-20 12:45:00 ... 0 $52.00 $0.00 0 01/21/2015 12:02:00 PM +0000 52 52 0 52 2015-01-21 12:02:00
2015-01-20 12:49:00 8CNX57 12 14 TOYOT MD 3500 BEECH AVE 22 Expired Tags $32.00 2015-01-20 12:49:00 ... 0 $32.00 $0.00 0 01/21/2015 12:02:00 PM +0000 32 32 0 32 2015-01-21 12:02:00
2015-01-20 12:49:00 JMS928 12 15 MAZDA MD 600 PACA ST 11 Residential Parking Permit Only $52.00 2015-01-20 12:49:00 ... 0 $52.00 $0.00 0 01/21/2015 12:02:00 PM +0000 52 52 0 52 2015-01-21 12:02:00
2015-01-20 12:51:00 BDP3268 8 15 HYUND NC 3000 CALVERT ST 11 Residential Parking Permit Only $52.00 2015-01-20 12:51:00 ... 0 $52.00 $0.00 0 01/21/2015 12:02:00 PM +0000 52 52 0 52 2015-01-21 12:02:00
2015-01-20 12:52:00 7DBL19 5 15 HONDA MD 600 PACA ST 11 Residential Parking Permit Only $52.00 2015-01-20 12:52:00 ... 0 $52.00 $0.00 0 01/21/2015 12:02:00 PM +0000 52 52 0 52 2015-01-21 12:02:00
2015-01-20 12:52:00 62484CE 3 16 JEEP MD U/B LAFAYETTE AVE 18 All Other Parking Meter Violations $32.00 2015-01-20 12:52:00 ... 0 $32.00 $0.00 0 01/21/2015 12:02:00 PM +0000 32 32 0 32 2015-01-21 12:02:00
2015-01-20 12:54:00 4AZ6632 2 15 NISSA MD U/B LAFAYETTE AVE 18 All Other Parking Meter Violations $32.00 2015-01-20 12:54:00 ... 0 $32.00 $0.00 0 01/21/2015 12:02:00 PM +0000 32 32 0 32 2015-01-21 12:02:00
2015-01-20 12:57:00 66033EN 8 15 HYUND IL 3100 CALVERT ST 11 Residential Parking Permit Only $52.00 2015-01-20 12:57:00 ... 0 $52.00 $0.00 0 01/21/2015 12:02:00 PM +0000 52 52 0 52 2015-01-21 12:02:00
2015-01-20 12:59:00 4BB1942 5 15 BMW MD 300 MOUNT ST 27 No Stop/Park Street Cleaning $52.00 2015-01-20 12:59:00 ... 0 $52.00 $0.00 0 01/21/2015 12:02:00 PM +0000 52 52 0 52 2015-01-21 12:02:00
2015-01-20 13:00:00 90842CE 5 15 HYUND MD 3100 CALVERT ST 11 Residential Parking Permit Only $52.00 2015-01-20 13:00:00 ... 0 $52.00 $0.00 0 01/21/2015 12:02:00 PM +0000 52 52 0 52 2015-01-21 12:02:00
2015-01-20 13:01:00 07152CF 9 15 HONDA MD 5500 BELAIR RD 18 All Other Parking Meter Violations $32.00 2015-01-20 13:01:00 ... 0 $32.00 $0.00 0 01/21/2015 12:02:00 PM +0000 32 32 0 32 2015-01-21 12:02:00
2015-01-20 13:04:00 JNW3513 5 15 NISSA PA 3100 CALVERT ST 11 Residential Parking Permit Only $52.00 2015-01-20 13:04:00 ... 0 $52.00 $0.00 0 01/21/2015 12:02:00 PM +0000 52 52 0 52 2015-01-21 12:02:00
2015-01-20 13:04:00 1EFV74 7 16 SCION MD 5100 ROLAND AVE 18 All Other Parking Meter Violations $32.00 2015-01-20 13:04:00 ... 0 $32.00 $0.00 0 01/21/2015 12:02:00 PM +0000 32 32 0 32 2015-01-21 12:02:00
2015-01-20 13:04:00 12871TL 1 17 TRAIL MD 300 POPPLETON ST 99 All Other Stopping or Parking Violations $32.00 2015-01-20 13:04:00 ... 0 $32.00 $0.00 0 01/21/2015 12:02:00 PM +0000 32 32 0 32 2015-01-21 12:02:00
2015-01-20 13:05:00 4CB2746 9 15 FORD ID 100 32ND ST 12 No Stopping/Standing Not Tow-Away Zone $32.00 2015-01-20 13:05:00 ... 0 $32.00 $0.00 0 01/21/2015 12:02:00 PM +0000 32 32 0 32 2015-01-21 12:02:00
2015-01-20 13:05:00 ND7315 11 15 SUBAR WV 100 LAFAYETTE AVE 18 All Other Parking Meter Violations $32.00 2015-01-20 13:05:00 ... 0 $32.00 $0.00 0 01/21/2015 12:02:00 PM +0000 32 32 0 32 2015-01-21 12:02:00
2015-01-20 13:06:00 4CMH23 1 16 CHEVR MD 5500 BELAIR RD 18 All Other Parking Meter Violations $32.00 2015-01-20 13:06:00 ... 0 $32.00 $0.00 0 01/21/2015 12:02:00 PM +0000 32 32 0 32 2015-01-21 12:02:00
2015-01-20 13:06:00 3FWT24 5 16 HONDA MD 300 POPPLETON ST 11 Residential Parking Permit Only $52.00 2015-01-20 13:06:00 ... 0 $52.00 $0.00 0 01/21/2015 12:02:00 PM +0000 52 52 0 52 2015-01-21 12:02:00
2015-01-20 13:06:00 4MYSONS 10 16 NISSA MD U/B MOUNT ST 18 All Other Parking Meter Violations $32.00 2015-01-20 13:06:00 ... 0 $32.00 $0.00 0 01/21/2015 12:02:00 PM +0000 32 32 0 32 2015-01-21 12:02:00
2015-01-20 13:07:00 V245498 11 15 NISSA IL 3100 CALVERT ST 11 Residential Parking Permit Only $52.00 2015-01-20 13:07:00 ... 0 $52.00 $0.00 0 01/21/2015 12:02:00 PM +0000 52 52 0 52 2015-01-21 12:02:00
2015-01-20 13:07:00 6BC1837 12 15 BMW MD 5100 ROLAND AVE 18 All Other Parking Meter Violations $32.00 2015-01-20 13:07:00 ... 0 $32.00 $0.00 0 01/21/2015 12:02:00 PM +0000 32 32 0 32 2015-01-21 12:02:00
2015-01-20 13:08:00 9AT1614 7 15 CHEVR MD 300 POPPLETON ST 11 Residential Parking Permit Only $52.00 2015-01-20 13:08:00 ... 0 $52.00 $0.00 0 01/21/2015 12:02:00 PM +0000 52 52 0 52 2015-01-21 12:02:00
2015-01-20 13:08:00 A240779 5 15 LINCO MD 2600 MARYLAND AVE 12 No Stopping/Standing Not Tow-Away Zone $32.00 2015-01-20 13:08:00 ... 0 $32.00 $0.00 0 01/21/2015 12:02:00 PM +0000 32 32 0 32 2015-01-21 12:02:00
2015-01-20 13:09:00 LRD868 9 15 HONDA MD 5100 ROLAND AVE 18 All Other Parking Meter Violations $32.00 2015-01-20 13:09:00 ... 0 $32.00 $0.00 0 01/21/2015 12:02:00 PM +0000 32 32 0 32 2015-01-21 12:02:00
2015-01-20 13:12:00 03080CF 11 15 HONDA MD U/B 22ND ST 18 All Other Parking Meter Violations $32.00 2015-01-20 13:12:00 ... 0 $32.00 $0.00 0 01/21/2015 12:02:00 PM +0000 32 32 0 32 2015-01-21 12:02:00
2015-01-20 13:12:00 7BD9888 7 15 TOYOT MD 3200 ST PAUL ST 18 All Other Parking Meter Violations $32.00 2015-01-20 13:12:00 ... 0 $32.00 $0.00 0 01/21/2015 12:02:00 PM +0000 32 32 0 32 2015-01-21 12:02:00
2015-01-20 13:14:00 6BG7778 11 15 TOYOT MD 5100 ROLAND AVE 18 All Other Parking Meter Violations $32.00 2015-01-20 13:14:00 ... 0 $32.00 $0.00 0 01/21/2015 12:02:00 PM +0000 32 32 0 32 2015-01-21 12:02:00
2015-01-20 13:15:00 9BK3957 4 16 CHEVR MD 1316 EDMONDSON AVE 27 No Stop/Park Street Cleaning $52.00 2015-01-20 13:15:00 ... 0 $52.00 $0.00 0 01/21/2015 12:02:00 PM +0000 52 52 0 52 2015-01-21 12:02:00
2015-01-20 13:17:00 MVL600 7 16 ACURA MD 5100 ROLAND AVE 18 All Other Parking Meter Violations $32.00 2015-01-20 13:17:00 ... 0 $32.00 $0.00 0 01/21/2015 12:02:00 PM +0000 32 32 0 32 2015-01-21 12:02:00
2015-01-20 13:17:00 67L907 9 15 CHEVR MD U/B 23RD ST 18 All Other Parking Meter Violations $32.00 2015-01-20 13:17:00 ... 0 $32.00 $0.00 0 01/21/2015 12:02:00 PM +0000 32 32 0 32 2015-01-21 12:02:00

515488 rows × 21 columns

In [138]:
fig = plt.figure(figsize=[8,6])
ax1 = plt.subplot(111)
plot(df_time_2.resample('M', how='count').index,
     df_time_2['tag'][df_time_2['openFine_parsed']==0].resample('M', how='count')/df_time_2['tag'].resample('M', how='count'),
     linewidth=2, color=red_orange)

# turn off square border around plot
ax1.spines["top"].set_visible(False)  
ax1.spines["bottom"].set_visible(False)  
ax1.spines["right"].set_visible(False)  
ax1.spines["left"].set_visible(False)

plt.ylim([0,1])
plt.xticks(rotation=45)
# turn off ticks
ax1.tick_params(axis="both", which="both", bottom="off", top="off",
               labelbottom="on", left="off", right="off", labelleft="on",labelsize=14)

title('% Monthly Citations Records With No Open Balance\n', fontsize=16)
plt.subplots_adjust(top=0.9, bottom=0.15)

fig.savefig('output/Monthly_Records_Paid.png', bbox_tight='inches')
In [125]:
red_orange = '#FF3300'

fig = plt.figure(figsize=[8,6])
ax1 = plt.subplot(111)
plot(df_time_2.resample('M', how='count').index,
     df_time_2['balance_parsed'][df_time_2['violFine_parsed']>0].resample('M', how='sum')/df_time_2['violFine_parsed'].resample('M', how='sum'),
     linewidth=2, color=red_orange)

# turn off square border around plot
ax1.spines["top"].set_visible(False)  
ax1.spines["bottom"].set_visible(False)  
ax1.spines["right"].set_visible(False)  
ax1.spines["left"].set_visible(False)

plt.ylim([0,1.1])
plt.xticks(rotation=45)
# turn off ticks
ax1.tick_params(axis="both", which="both", bottom="off", top="off",
               labelbottom="on", left="off", right="off", labelleft="on",labelsize=14)

title('% Monthly Citations Records With No Open Balance\n', fontsize=18)
Out[125]:
<matplotlib.text.Text at 0x10fab42d0>
In [134]:
df_time_2.resample('M', how='count').index
Out[134]:
<class 'pandas.tseries.index.DatetimeIndex'>
[2013-01-31, ..., 2015-01-31]
Length: 25, Freq: M, Timezone: None

My Block

In [41]:
block_1200_Charles = groupby_loc.get_group('1200 CHARLES ST').groupby('Description')
In [123]:
print 'Fines Issued at 1200 N. Charles St.\n'

block_1200_Charles_fines = pd.DataFrame(columns=['total_fines_issued'])

for key, group in block_1200_Charles:
    
    #print key, block_1200_Charles['violFine_parsed'].get_group(key).sum()

    block_1200_Charles_fines.ix[key] = block_1200_Charles['violFine_parsed'].get_group(key).sum()
    
block_1200_Charles_fines.sort('total_fines_issued',ascending=False, inplace=True)
block_1200_Charles_fines.to_csv('output/1200_Block_N_Charles.csv')    
block_1200_Charles_fines
Fines Issued at 1200 N. Charles St.

Out[123]:
total_fines_issued
All Other Parking Meter Violations 50816
Residential Parking Permit Only 31980
No Stopping/Standing Tow Away Zone 30420
No Stopping//Parking Stadium Event Camden 22440
In Transit Zone/Stop 18557
No Stop/Park Street Cleaning 8632
Expired Tags 3584
No Stopping/Standing Not Tow-Away Zone 2336
Less Than 15 feet from Fire Hydrant 2079
Passenger Loading Zone 928
Obstruct/Impeding Flow of Traffic 510
Obstruct/Impeding Movement of Pedestrian 385
All Other Stopping or Parking Violations 256
In [54]:
block_1200_Charles['violFine_parsed'].get_group(key).sum()
Out[54]:
31980.0
In [79]:
 
Out[79]:
total_fines_issued
All Other Parking Meter Violations 50816
All Other Stopping or Parking Violations 256
Expired Tags 3584
In Transit Zone/Stop 18557
Less Than 15 feet from Fire Hydrant 2079
No Stop/Park Street Cleaning 8632
No Stopping//Parking Stadium Event Camden 22440
No Stopping/Standing Not Tow-Away Zone 2336
No Stopping/Standing Tow Away Zone 30420
Obstruct/Impeding Flow of Traffic 510
Obstruct/Impeding Movement of Pedestrian 385
Passenger Loading Zone 928
Residential Parking Permit Only 31980
In [85]:
 
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-85-d16530bb44ab> in <module>()
----> 1 import plot.ly

ImportError: No module named plot.ly
In [119]:
groupby_loc.get_group('1200 CHARLES ST').groupby('Description').count()
Out[119]:
tag expmm expyy make state location violCode violFine violDate balance penaltyDate openFine openPenalty noticeDate ImportDate violFine_parsed openFine_parsed openPenalty_parsed balance_parsed ImportDate_parsed
Description
All Other Parking Meter Violations 1588 1588 1588 1588 1588 1588 1588 1588 1588 1588 1588 1588 1588 1588 1588 1588 1588 1588 1588 1588
All Other Stopping or Parking Violations 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
Expired Tags 112 112 112 112 112 112 112 112 112 112 112 112 112 112 112 112 112 112 112 112
In Transit Zone/Stop 241 241 241 241 241 241 241 241 241 241 241 241 241 241 241 241 241 241 241 241
Less Than 15 feet from Fire Hydrant 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27 27
No Stop/Park Street Cleaning 166 166 166 166 166 166 166 166 166 166 166 166 166 166 166 166 166 166 166 166
No Stopping//Parking Stadium Event Camden 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220 220
No Stopping/Standing Not Tow-Away Zone 73 73 73 73 73 73 73 73 73 73 73 73 73 73 73 73 73 73 73 73
No Stopping/Standing Tow Away Zone 585 585 585 585 585 585 585 585 585 585 585 585 585 585 585 585 585 585 585 585
Obstruct/Impeding Flow of Traffic 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
Obstruct/Impeding Movement of Pedestrian 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
Passenger Loading Zone 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29
Residential Parking Permit Only 615 615 615 615 615 615 615 615 615 615 615 615 615 615 615 615 615 615 615 615
In [153]:
(df_time_2['violFine_parsed'].resample('D',how='sum')/df_time_2['balance_parsed'].resample('D',how='sum')).plot()
Out[153]:
<matplotlib.axes._subplots.AxesSubplot at 0x111c0ded0>
In [157]:
(df_time_2['balance_parsed'].resample('M',how='sum')/df_time_2['violFine_parsed'].resample('M',how='sum')).plot()
Out[157]:
<matplotlib.axes._subplots.AxesSubplot at 0x1113cf610>
In [159]:
(df_time_2['balance_parsed'][df_time_2['balance_parsed']==0].resample('M',how='count')/df_time_2['violFine_parsed'].resample('M',how='count')).plot()
Out[159]:
<matplotlib.axes._subplots.AxesSubplot at 0x10faeec50>
In [161]:
df_time_2['balance_parsed'][df_time_2['balance_parsed']==0].resample('M',how='count')
Out[161]:
violDate
2013-01-31      454
2013-02-28     1470
2013-03-31     3192
2013-04-30     2504
2013-05-31     2353
2013-06-30     2680
2013-07-31     3872
2013-08-31     4367
2013-09-30     4636
2013-10-31     7079
2013-11-30     8999
2013-12-31    15385
2014-01-31    25413
2014-02-28    25921
2014-03-31    31351
2014-04-30    29706
2014-05-31    28504
2014-06-30    26010
2014-07-31    26758
2014-08-31    25209
2014-09-30    22809
2014-10-31    22833
2014-11-30    17444
2014-12-31    16604
2015-01-31     1920
Freq: M, Name: balance_parsed, dtype: int64
In [162]:
df_time_2['violFine_parsed'].resample('M',how='count')
Out[162]:
violDate
2013-01-31     1642
2013-02-28     4657
2013-03-31    10090
2013-04-30     7084
2013-05-31     6284
2013-06-30     6541
2013-07-31     8034
2013-08-31     8585
2013-09-30     8157
2013-10-31    11269
2013-11-30    12999
2013-12-31    19531
2014-01-31    29238
2014-02-28    29514
2014-03-31    36614
2014-04-30    35166
2014-05-31    34387
2014-06-30    32294
2014-07-31    34428
2014-08-31    32631
2014-09-30    30457
2014-10-31    32193
2014-11-30    27931
2014-12-31    38547
2015-01-31    17245
Freq: M, Name: violFine_parsed, dtype: int64
In [173]:
fig = plt.figure()

(df_time_2['openFine_parsed'].resample('D',how='sum')/df_time_2['violFine_parsed'].resample('D',how='sum')).plot()
(df_time_2['openPenalty_parsed'].resample('D',how='sum')/df_time_2['violFine_parsed'].resample('D',how='sum')).plot()

plt.grid('off')

legend(['Total Open Fines / Total Fines','Total Open Penalties / Total Fines'])
Out[173]:
<matplotlib.legend.Legend at 0x112ec2550>

A couple of things may be going on here but I have a hunch. Through 2013 there was a massive uptick in the number of total parking fines issued, while over the course of 2014 the total parking fines issued was relatively consistent. Since the 2013 is a shifting sample size we might be seeing a regression towards the mean, though at 5,000 to 10,000 total citations issued this really shouldn't be the case. So why would there be a massive change over time in the percentage of fines and penalties paid? I think what might be going on is that due to the shift in policing tactics, more affluent neighborhoods started to become targets for parking citations, which resulted in parking fines being much more quickly paid. If you haven't paid it in a year why would you be more likely to pay it off within two with such a dramatic increase in likelihood? In other words, why should there be such a radical change in the slope of the curves at January 2014?

Okay, maybe penalties increase at 1 year pretty steeply... but looking at the blue curve only (open fines) there is still a change in behavior at Jan 2014. Open

In [175]:
fig = plt.figure()

(df_time_2['balance_parsed'][df_time_2['balance_parsed']==0].resample('M',how='count')/df_time_2['violFine_parsed'].resample('M',how='count')).plot()

plt.grid('off')

#legend(['Total Open Fines / Total Fines','Total Open Penalties / Total Fines'])
In [303]:
import plotly.plotly as py

fig = plt.figure(figsize=[8,6])
ax1 = plt.subplot(1,1,1)

plot1 = (df_time_2['openFine_parsed'].resample('D',how='sum')/df_time_2['violFine_parsed'].resample('D',how='sum')).plot(color=red_orange)
#(df_time_2['openPenalty_parsed'].resample('D',how='sum')/df_time_2['violFine_parsed'].resample('D',how='sum')).plot()
linear_ext = pd.DataFrame([.03, .11],index=[pd.to_datetime('01-feb-2013'),pd.to_datetime('20-dec-2013')])
plot2 = linear_ext[0].plot(color=red_orange, linestyle='--', linewidth=3)


# turn off square border around plot
ax1.spines["top"].set_visible(False)  
ax1.spines["bottom"].set_visible(False)  
ax1.spines["right"].set_visible(False)  
ax1.spines["left"].set_visible(False)

plt.ylim([0,1.1])
#plt.xticks(rotation=45)
# turn off ticks
ax1.tick_params(axis="both", which="both", bottom="off", top="off",
               labelbottom="on", left="off", right="off", labelleft="on",labelsize=14)

plt.title('% Daily Total Fines Issued Remaining Unpaid', fontsize=18)
plt.xlabel('')
plt.grid('off')

#fig.savefig('output/Daily_Total_Fines_Unpaid.png', bbox_tight='inches')
#py.iplot_mpl(fig)
In [13]:
fig = plt.figure(figsize=[8,6])
ax1 = plt.subplot(1,1,1)

plot1 = (df_time_2['openFine_parsed'][df_time_2['openFine_parsed']>0].resample('D',how='count')/df_time_2['violFine_parsed'].resample('D',how='count')).plot(color=red_orange)
#(df_time_2['openPenalty_parsed'].resample('D',how='sum')/df_time_2['violFine_parsed'].resample('D',how='sum')).plot()
linear_ext = pd.DataFrame([.03, .11],index=[pd.to_datetime('01-feb-2013'),pd.to_datetime('20-dec-2013')])
plot2 = linear_ext[0].plot(color=red_orange, linestyle='--', linewidth=3)


# turn off square border around plot
ax1.spines["top"].set_visible(False)  
ax1.spines["bottom"].set_visible(False)  
ax1.spines["right"].set_visible(False)  
ax1.spines["left"].set_visible(False)

plt.ylim([0,1.1])
#plt.xticks(rotation=45)
# turn off ticks
ax1.tick_params(axis="both", which="both", bottom="off", top="off",
               labelbottom="on", left="off", right="off", labelleft="on",labelsize=14)

plt.title('% Daily Number Citations Issued Remaining Unpaid', fontsize=18)
plt.xlabel('')
plt.grid('off')

#fig.savefig('output/Daily_Citations_Unpaid.png', bbox_tight='inches')
In [309]:
df_time_2['openFine_parsed'].resample('D',how='count')
#df_time_2['openFine_parsed'][df_time_2['openFine_parsed']>0].resample('D',how='count')
Out[309]:
violDate
2013-01-21     31
2013-01-22    228
2013-01-23    171
2013-01-24    139
2013-01-25    178
2013-01-26     85
2013-01-27     70
2013-01-28    199
2013-01-29    180
2013-01-30    165
2013-01-31    196
2013-02-01    214
2013-02-02     82
2013-02-03     59
2013-02-04    199
...
2015-01-06     673
2015-01-07    1143
2015-01-08    1033
2015-01-09    1103
2015-01-10     774
2015-01-11     279
2015-01-12    1212
2015-01-13    1277
2015-01-14    1206
2015-01-15    1231
2015-01-16    1271
2015-01-17     863
2015-01-18     483
2015-01-19       0
2015-01-20     469
Freq: D, Name: openFine_parsed, Length: 730

Need heat map for 2013 citations and 2014 citations.

In [10]:
df_time_2['city'] = 'Baltimore'
df_time_2['state'] = 'MD'
#df_time_2[['location','city','state']].ix['2013'].to_csv('output/2013_citation_locations.csv')
#df_time_2[['location','city','state']].ix['2014'].to_csv('output/2014_citation_locations.csv')
-c:1: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
-c:2: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
In [39]:
# Random samples for mapping purposes
N = 1000

df_2013 = df_time_2[['tag','location','city','state']].ix['2013']
df_2014 = df_time_2[['tag','location','city','state']].ix['2014']

sample_2013 = df_2013.iloc[np.random.choice(len(df_2013), N, replace=False)]
#sample_2013.to_csv('output/2013_random_sample.csv')

sample_2014 = df_2014.iloc[np.random.choice(len(df_2014), N, replace=False)]
#sample_2014.to_csv('output/2014_random_sample.csv')
In [44]:
block_1200_Charles['violFine_parsed'].plot()
Out[44]:
Description
All Other Parking Meter Violations           Axes(0.125,0.2;0.775x0.7)
All Other Stopping or Parking Violations     Axes(0.125,0.2;0.775x0.7)
Expired Tags                                 Axes(0.125,0.2;0.775x0.7)
In Transit Zone/Stop                         Axes(0.125,0.2;0.775x0.7)
Less Than 15 feet from Fire Hydrant          Axes(0.125,0.2;0.775x0.7)
No Stop/Park Street Cleaning                 Axes(0.125,0.2;0.775x0.7)
No Stopping//Parking Stadium Event Camden    Axes(0.125,0.2;0.775x0.7)
No Stopping/Standing Not Tow-Away Zone       Axes(0.125,0.2;0.775x0.7)
No Stopping/Standing Tow Away Zone           Axes(0.125,0.2;0.775x0.7)
Obstruct/Impeding Flow of Traffic            Axes(0.125,0.2;0.775x0.7)
Obstruct/Impeding Movement of Pedestrian     Axes(0.125,0.2;0.775x0.7)
Passenger Loading Zone                       Axes(0.125,0.2;0.775x0.7)
Residential Parking Permit Only              Axes(0.125,0.2;0.775x0.7)
Name: violFine_parsed, dtype: object
In [53]:
df_time_2['violFine_parsed'][df_time_2['location']=='1200 CHARLES ST'].resample('M',how='sum').plot()
Out[53]:
<matplotlib.axes._subplots.AxesSubplot at 0x115f58c50>
In [76]:
np.std(df_time_2['violFine_parsed'].ix['2014'].resample('D',how='sum'))
Out[76]:
18292.344801019481
In [77]:
np.std(df_time_2['violFine_parsed'].ix['2013'].resample('D',how='sum'))
Out[77]:
9032.7358844832925

Blocks with largest citation number increase

In [14]:
# Overall monthly citation increase
fig = plt.figure(figsize=[8,6])
ax1 = plt.subplot(1,1,1)

plot1 = df_time_2['violFine_parsed'].ix[:'dec-2014'].resample('M',how='count').plot(color=red_orange, grid='off',linewidth=3)

# turn off square border around plot
ax1.spines["top"].set_visible(False)  
ax1.spines["bottom"].set_visible(False)  
ax1.spines["right"].set_visible(False)  
ax1.spines["left"].set_visible(False)

#plt.ylim([0,1.1])
#plt.xticks(rotation=45)
# turn off ticks
ax1.tick_params(axis="both", which="both", bottom="off", top="off",
               labelbottom="on", left="off", right="off", labelleft="on",labelsize=14)

plt.ylabel('Total Monthly Number of Citations', fontsize=16)
plt.xlabel('')

#fig.savefig('output/Total_Monthly_Citations.png', bbox_tight='inches')
Out[14]:
<matplotlib.text.Text at 0x111eb1c90>
In [131]:
# % Increase Sept 2013 to Mar 2014

Overall Ratio, March 2014 citations to September 2013 citations.

In [187]:
print 'Overall Ratio, March 2014 citations to September 2013 citations: ',round(float(df_time_2['violFine_parsed'].ix['mar-2014'].count()) / float(df_time_2['violFine_parsed'].ix['sept-2013'].count()), 2)
Overall Ratio, March 2014 citations to September 2013 citations:  4.49
In [15]:
# FIRST NEED TO SLICE OUT ONLY LOCATIONS WITH TICKETS IN Sep 2013 and Mar 2014
#sep13_uniq_locs = df_time_2['location'].ix['sep-2013'].unique()
mar14_uniq_locs = df_time_2['location'].ix['mar-2014'].unique()

a = df_time_2[df_time_2['location'].isin(mar14_uniq_locs)]
#b = a[a['location'].isin(mar14_uniq_locs)]

Mar14_Sep13 = pd.DataFrame()
Mar14_Sep13['Mar_2014'] = a['location'].ix['Mar-2014'].value_counts()
Mar14_Sep13['Sept_2013'] = a['location'].ix['Sept-2013'].value_counts()
Mar14_Sep13['Sept_2013'].fillna(0, inplace=True)
Mar14_Sep13['Diff'] = Mar14_Sep13['Mar_2014'] - Mar14_Sep13['Sept_2013']
Mar14_Sep13['Ratio'] = Mar14_Sep13['Mar_2014'] / Mar14_Sep13['Sept_2013']

Mar14_Sep13.sort('Diff', ascending=False, inplace=True)
Mar14_Sep13[:25]
#Mar14_Sep13[:25].to_csv('output/Top_25_Increase_Citations_Sept13_Mar14_Locs.csv')
Out[15]:
Mar_2014 Sept_2013 Diff Ratio
U/B CROSS ST 375 27 348 13.888889
1000 CHARLES ST 285 23 262 12.391304
U/B SOUTH ST 286 45 241 6.355556
1700 THAMES ST 278 43 235 6.465116
1200 CHARLES ST 271 55 216 4.927273
700 BROADWAY 229 21 208 10.904762
400 LOT JFA 198 0 198 inf
U/B CALVERT ST 232 48 184 4.833333
1000 LIGHT ST 194 14 180 13.857143
800 BROADWAY 202 22 180 9.181818
U/B PACA ST 215 44 171 4.886364
U/B GAY ST 196 27 169 7.259259
700 CENTRAL AVE 188 26 162 7.230769
U/B COMMERCE ST 202 53 149 3.811321
1100 LIGHT ST 145 12 133 12.083333
1600 THAMES ST 147 15 132 9.800000
1100 CHARLES ST 144 25 119 5.760000
800 ALICEANNA ST 135 16 119 8.437500
900 CHARLES ST 130 12 118 10.833333
1300 CHARLES ST 135 20 115 6.750000
3200 LOT WAVERLY 114 0 114 inf
300 CALVERT ST 144 32 112 4.500000
5100 ROLAND AVE 114 3 111 38.000000
U/B READ ST 141 32 109 4.406250
200 BROADWAY 113 6 107 18.833333

Looks like the 400 lot under the JFA and the 3200 lot of Waverly are newly targeted locations as of February 2014. Behavior for 3200 Waverly lot makes sense.

In [280]:
df_time_2['tag'][df_time_2['location']=='400 LOT JFA'].ix[:'dec-2014'].resample('M', how='count').plot()
Out[280]:
<matplotlib.axes._subplots.AxesSubplot at 0x112ec2250>
In [16]:
a = df_time_2[df_time_2['location']=='400 LOT JFA'].groupby('Description')
a['tag'].count()
Out[16]:
Description
All Other Parking Meter Violations          568
All Other Stopping or Parking Violations    306
Expired Tags                                 24
No Stop/Park Handicap                        17
No Stopping/Standing Tow Away Zone           72
Name: tag, dtype: int64
In [283]:
df_time_2['tag'][df_time_2['location']=='3200 LOT WAVERLY'].ix[:'dec-2014'].resample('M', how='count').plot()
Out[283]:
<matplotlib.axes._subplots.AxesSubplot at 0x113777cd0>
In [17]:
fig = plt.figure(figsize=[8,6])
ax1 = plt.subplot(1,1,1)
plot1 = df_time_2['tag'][df_time_2['location']=='5100 ROLAND AVE'].ix[:'dec-2014'].resample('M', how='count').plot(grid='off', color=red_orange, linewidth=3)

# turn off square border around plot
ax1.spines["top"].set_visible(False)  
ax1.spines["bottom"].set_visible(False)  
ax1.spines["right"].set_visible(False)  
ax1.spines["left"].set_visible(False)

#plt.ylim([0,1.1])
#plt.xticks(rotation=45)
# turn off ticks
ax1.tick_params(axis="both", which="both", bottom="off", top="off",
               labelbottom="on", left="off", right="off", labelleft="on",labelsize=14)

plt.ylabel('Total Monthly Number of Citations', fontsize=16)
plt.xlabel('')
plt.title('5100 Roland Ave.', fontsize=16)

#fig.savefig('output/5100_Roland_Citations.png', bbox_tight='inches')
Out[17]:
<matplotlib.text.Text at 0x11c3b4410>
In [297]:
a = df_time_2[df_time_2['location']=='5100 ROLAND AVE'].groupby('Description')
a['tag'].count()
Out[297]:
Description
All Other Parking Meter Violations          1111
All Other Stopping or Parking Violations       7
Expired Tags                                  47
In Transit Zone/Stop                          63
Less Than 15 feet from Fire Hydrant           41
No Stopping/Standing Not Tow-Away Zone       131
Residential Parking Permit Only               10
Name: tag, dtype: int64

4200 Wickford Rd.

In [18]:
fig = plt.figure(figsize=[10,6])
ax1 = plt.subplot(1,1,1)

# convert resampled index to right date format
my_x_labels = df_time_2['violFine_parsed'][df_time_2['location']=='4200 WICKFORD RD'].resample('M',how='count').index.map(lambda x: x.strftime('%b %Y'))

plot1= bar(xrange(len(my_x_labels)),
            df_time_2['violFine_parsed'][df_time_2['location']=='4200 WICKFORD RD'].resample('M',how='count'),
            align='center',
            color=red_orange)
xlim([0,len(my_x_labels)])

# turn off square border around plot
ax1.spines["top"].set_visible(False)  
ax1.spines["bottom"].set_visible(False)  
ax1.spines["right"].set_visible(False)  
ax1.spines["left"].set_visible(False)

plt.xticks(xrange(len(df_time_2['violFine_parsed'][df_time_2['location']=='4200 WICKFORD RD'].resample('M',how='count'))),my_x_labels,ha='center',rotation=90)

# turn off ticks
ax1.tick_params(axis="both", which="both", bottom="off", top="off",
               labelbottom="on", left="off", right="off", labelleft="on",labelsize=14)

#title('4200 Wickford Rd.', fontsize=20)
text(len(my_x_labels)-1,24,'4200 Wickford Rd.',ha='right',fontsize=20)
plt.subplots_adjust(top=0.95, bottom=0.2)
ylabel('Monthly Ticket Count', fontsize=16)
#fig.savefig('output/4200_Wickford.png', bbox_tight='inches')
Out[18]:
<matplotlib.text.Text at 0x11859c090>
In [104]:
df_time_2['violFine_parsed'][df_time_2['location']=='4200 WICKFORD RD'].count()#.to_csv('output/4200_Wickford_Citations.csv')
Out[104]:
41
In [105]:
df_time_2['Description'][df_time_2['location']=='4200 WICKFORD RD']#.to_csv('output/4200_Wickford_Citations.csv')
Out[105]:
violDate
2013-07-05 12:21:00                                Expired Tags
2014-02-11 11:14:00                                Expired Tags
2014-02-12 20:46:00    All Other Stopping or Parking Violations
2014-03-04 14:17:00                                Expired Tags
2014-04-04 04:32:00    All Other Stopping or Parking Violations
2014-04-04 04:35:00    All Other Stopping or Parking Violations
2014-04-04 04:38:00    All Other Stopping or Parking Violations
2014-04-04 04:38:00    All Other Stopping or Parking Violations
2014-04-08 17:04:00    All Other Stopping or Parking Violations
2014-04-08 17:06:00    All Other Stopping or Parking Violations
2014-04-08 17:07:00    All Other Stopping or Parking Violations
2014-04-08 17:09:00    All Other Stopping or Parking Violations
2014-04-08 17:10:00    All Other Stopping or Parking Violations
2014-04-08 17:12:00    All Other Stopping or Parking Violations
2014-04-08 17:14:00                                Expired Tags
2014-04-08 17:16:00    All Other Stopping or Parking Violations
2014-04-08 17:17:00    All Other Stopping or Parking Violations
2014-04-10 04:37:00    All Other Stopping or Parking Violations
2014-04-10 04:39:00    All Other Stopping or Parking Violations
2014-04-10 04:43:00    All Other Stopping or Parking Violations
2014-04-10 04:46:00    All Other Stopping or Parking Violations
2014-04-18 02:26:00    All Other Stopping or Parking Violations
2014-04-18 02:28:00    All Other Stopping or Parking Violations
2014-04-18 02:29:00    All Other Stopping or Parking Violations
2014-04-18 02:31:00    All Other Stopping or Parking Violations
2014-05-20 13:51:00                                Expired Tags
2014-05-27 11:52:00                          Exceeding 48 Hours
2014-07-18 14:31:00                          Exceeding 48 Hours
2014-11-08 20:28:00    All Other Stopping or Parking Violations
2014-11-08 20:30:00    All Other Stopping or Parking Violations
2014-11-08 20:31:00    All Other Stopping or Parking Violations
2014-11-08 20:33:00    All Other Stopping or Parking Violations
2014-11-08 20:34:00    All Other Stopping or Parking Violations
2014-11-08 20:35:00    All Other Stopping or Parking Violations
2014-11-08 20:38:00    All Other Stopping or Parking Violations
2014-11-08 20:39:00    All Other Stopping or Parking Violations
2014-11-08 20:39:00    All Other Stopping or Parking Violations
2014-11-08 20:40:00    All Other Stopping or Parking Violations
2014-12-12 10:24:00    All Other Stopping or Parking Violations
2014-12-12 10:26:00    All Other Stopping or Parking Violations
2014-12-12 10:40:00                                Expired Tags
Name: Description, dtype: object

When Not To Park On N. Charles St.

This section is looking only at the highly ticketed 5 blocks on N. Charles St.

In [26]:
Charles_St = ['900 CHARLES ST',
              '1000 CHARLES ST',
              '1100 CHARLES ST',
              '1200 CHARLES ST',
              '1300 CHARLES ST']
In [145]:
# All days

Charles_St_citations = df_time_2[df_time_2['location'].isin(Charles_St)]

Charles_St_hour_count = Charles_St_citations['tag'].groupby(Charles_St_citations.index.hour).count()
bar(Charles_St_hour_count.index,Charles_St_hour_count)
Out[145]:
<Container object of 24 artists>
In [100]:
# Charles St Weekend

Charles_St_citations_weekend = Charles_St_citations.ix[(Charles_St_citations.index.dayofweek==5) | (Charles_St_citations.index.dayofweek==6)]
Charles_St_citations_weekend_hour_count = Charles_St_citations_weekend['tag'].groupby(Charles_St_citations_weekend.index.hour).count()
bar(Charles_St_citations_weekend_hour_count.index,Charles_St_citations_weekend_hour_count,align='center')
xlim([-1,24])
plt.show()
#Charles_St_citations_weekday = Charles_St_citations.index.dayofweek.isin([0,1,2,3,4])
In [148]:
# Charles St Weekday

Charles_St_citations_weekday = Charles_St_citations.ix[Charles_St_citations.index.dayofweek<5]
Charles_St_citations_weekday_hour_count = Charles_St_citations_weekday['tag'].groupby(Charles_St_citations_weekday.index.hour).count()
bar(Charles_St_citations_weekday_hour_count.index,Charles_St_citations_weekday_hour_count,align='center')
xlim([-1,24])
plt.show()
In [261]:
# Total citation counts on 5 blocks of N. Charles St. by day of week
fig = plt.figure(figsize=[8,6])
ax1 = plt.subplot(1,1,1)

my_x_labels = ['Mon','Tues','Weds','Thurs','Fri','Sat','Sun']

a=Charles_St_citations.groupby(Charles_St_citations.index.dayofweek)
a['tag'].count().plot(kind='bar', grid='off', color=red_orange)

# turn off square border around plot
ax1.spines["top"].set_visible(False)  
ax1.spines["bottom"].set_visible(False)  
ax1.spines["right"].set_visible(False)  
ax1.spines["left"].set_visible(False)

# turn off ticks
ax1.tick_params(axis="both", which="both", bottom="off", top="off",
               labelbottom="on", left="off", right="off", labelleft="on",labelsize=14)

text(6.25,2500,'N. Charles St. \n Citations',ha='right',va='center',fontsize=20)
ylabel('Citations', fontsize=16)
xticks(range(0,7),my_x_labels, rotation=0)
plt.show()

fig.savefig('output/N_Charles_by_Day.png', bbox_tight='inches')
In [236]:
Charles_St_citations.groupby('Description')['tag'].count()
Out[236]:
Description
All Other Parking Meter Violations           8226
All Other Stopping or Parking Violations       30
Commercial Veh/Residence over 20,000 lbs        1
Expired Tags                                  491
In Taxicab Stand                                3
In Transit Zone/Stop                          342
Less Than 15 feet from Fire Hydrant            34
No Stop/Park Street Cleaning                  536
No Stopping//Parking Stadium Event Camden     269
No Stopping/Standing Not Tow-Away Zone        535
No Stopping/Standing Tow Away Zone           1796
Obstruct/Impeding Flow of Traffic              21
Obstruct/Impeding Movement of Pedestrian       32
Passenger Loading Zone                        110
Residential Parking Permit Only               732
Name: tag, dtype: int64
In [262]:
fig = plt.figure(figsize=[10,8])
ax1 = plt.subplot(1,1,1)

a=pd.DataFrame(pd.Series(Charles_St_citations_weekday.index.hour).value_counts(),index=range(0,23))
b=pd.DataFrame(pd.Series(Charles_St_citations_weekend.index.hour).value_counts(),index=range(0,23))
b.fillna(0,inplace=True)
a.sort(inplace=True)
b.sort(inplace=True)
bar(b.index,b[0],color=light_cyan,align='center')
bar(a.index,a[0],color=gray_light,bottom=b[0],align='center')

xlim([-1,24])
xlabel('Hour of Day', fontsize=16)
ylabel('Citations', fontsize=16)
text(0,2000,'N. Charles St. Citations',ha='left',va='center',fontsize=20)
legend(['Weekend','Weekday'],loc='upper left', fontsize=16, frameon=False,
       bbox_to_anchor=(.14, -.13, 1, 1),
       bbox_transform=gcf().transFigure)

# turn off square border around plot
ax1.spines["top"].set_visible(False)  
ax1.spines["bottom"].set_visible(False)  
ax1.spines["right"].set_visible(False)  
ax1.spines["left"].set_visible(False)

# turn off ticks
ax1.tick_params(axis="both", which="both", bottom="off", top="off",
               labelbottom="on", left="off", right="off", labelleft="on",labelsize=14)

fig.savefig('output/N_Charles_by_Hour.png', bbox_inches='tight')
In [166]:
b
Out[166]:
0
0 63
1 28
2 5
3 0
4 1
5 0
6 1
7 0
8 1
9 14
10 155
11 159
12 102
13 125
14 185
15 90
16 290
17 366
18 220
19 190
20 134
21 70
22 49
In [233]:
Charles_St_citations
Out[233]:
tag expmm expyy make state location violCode Description violFine violDate ... penaltyDate openFine openPenalty noticeDate ImportDate violFine_parsed openFine_parsed openPenalty_parsed balance_parsed ImportDate_parsed
violDate
2013-02-01 11:17:00 79AC88 08 14 FORD MD 1100 CHARLES ST 18 All Other Parking Meter Violations $32.00 2013-02-01 11:17:00 ... 0 $32.00 $0.00 0 05/07/2013 05:41:00 PM +0000 32 32 0 32 2013-05-07 17:41:00
2013-02-01 13:35:00 7EDY48 09 14 CHEVR MD 1200 CHARLES ST 18 All Other Parking Meter Violations $32.00 2013-02-01 13:35:00 ... 0 $0.00 $0.00 02/27/2013 12/20/2013 12:03:00 PM +0000 32 0 0 0 2013-12-20 12:03:00
2013-02-04 18:24:00 HOPE 05 14 NISSA MD 1200 CHARLES ST 11 Residential Parking Permit Only $52.00 2013-02-04 18:24:00 ... 0 $52.00 $0.00 0 05/07/2013 05:41:00 PM +0000 52 52 0 52 2013-05-07 17:41:00
2013-02-07 12:14:00 99952CD 07 13 HONDA MD 1200 CHARLES ST 18 All Other Parking Meter Violations $32.00 2013-02-07 12:14:00 ... 0 $0.00 $0.00 03/05/2013 03/19/2014 11:02:00 AM +0000 32 0 0 0 2014-03-19 11:02:00
2013-02-08 09:37:00 9FBK89 06 14 LINCO MD 1100 CHARLES ST 20 Passenger Loading Zone $32.00 2013-02-08 09:37:00 ... 0 $32.00 $325.00 03/05/2013 10/09/2014 11:02:00 AM +0000 32 32 325 357 2014-10-09 11:02:00
2013-02-08 09:45:00 1GBS84 05 14 CHEVR MD 1200 CHARLES ST 18 All Other Parking Meter Violations $32.00 2013-02-08 09:45:00 ... 0 $0.00 $0.00 03/05/2013 05/31/2014 11:03:00 AM +0000 32 0 0 0 2014-05-31 11:03:00
2013-02-09 17:48:00 2AY5263 11 14 CHRYS MD 1000 CHARLES ST 18 All Other Parking Meter Violations $32.00 2013-02-09 17:48:00 ... 0 $0.00 $0.00 03/05/2013 02/06/2014 12:02:00 PM +0000 32 0 0 0 2014-02-06 12:02:00
2013-02-09 20:25:00 T648794T 02 13 HONDA MD 900 CHARLES ST 12 No Stopping/Standing Not Tow-Away Zone $32.00 2013-02-09 20:25:00 ... 0 $32.00 $0.00 0 05/07/2013 05:41:00 PM +0000 32 32 0 32 2013-05-07 17:41:00
2013-02-09 20:44:00 H8RSOX 08 14 NISSA NY 1200 CHARLES ST 11 Residential Parking Permit Only $52.00 2013-02-09 20:44:00 ... 0 $52.00 $304.00 07/01/2013 01/09/2015 12:02:00 PM +0000 52 52 304 356 2015-01-09 12:02:00
2013-02-11 10:51:00 9AC7613 12 14 KIA MD 1000 CHARLES ST 18 All Other Parking Meter Violations $32.00 2013-02-11 10:51:00 ... 0 $32.00 $0.00 0 02/13/2013 12:03:00 PM +0000 32 32 0 32 2013-02-13 12:03:00
2013-02-11 12:57:00 4MD9930 06 14 HONDA MD 1300 CHARLES ST 18 All Other Parking Meter Violations $32.00 2013-02-11 12:57:00 ... 0 $32.00 $325.00 03/05/2013 10/09/2014 11:02:00 AM +0000 32 32 325 357 2014-10-09 11:02:00
2013-02-11 13:08:00 4AB7759 11 12 INFIN MD 1200 CHARLES ST 22 Expired Tags $32.00 2013-02-11 13:08:00 ... 0 $32.00 $300.00 03/05/2013 10/09/2014 11:02:00 AM +0000 32 32 300 332 2014-10-09 11:02:00
2013-02-12 11:46:00 9AL5922 11 14 ACURA MD 1200 CHARLES ST 18 All Other Parking Meter Violations $32.00 2013-02-12 11:46:00 ... 0 $32.00 $325.00 03/05/2013 10/09/2014 11:02:00 AM +0000 32 32 325 357 2014-10-09 11:02:00
2013-02-13 11:07:00 ZCJ1792 05 13 CHEVR PA 900 CHARLES ST 18 All Other Parking Meter Violations $32.00 2013-02-13 11:07:00 ... 0 $0.00 $0.00 09/03/2013 05/30/2014 11:02:00 AM +0000 32 0 0 0 2014-05-30 11:02:00
2013-02-13 13:15:00 MEG185 02 16 HYUND MD 1200 CHARLES ST 18 All Other Parking Meter Violations $32.00 2013-02-13 13:15:00 ... 0 $25.00 $149.00 03/13/2013 10/23/2014 11:02:00 AM +0000 32 25 149 174 2014-10-23 11:02:00
2013-02-13 13:58:00 HNZ6011 11 13 OLDSM PA 1200 CHARLES ST 18 All Other Parking Meter Violations $32.00 2013-02-13 13:58:00 ... 0 $0.00 $0.00 09/03/2013 04/03/2014 11:02:00 AM +0000 32 0 0 0 2014-04-03 11:02:00
2013-02-15 12:40:00 8AB1723 10 14 HYUND MD 900 CHARLES ST 22 Expired Tags $32.00 2013-02-15 12:40:00 ... 0 $0.00 $0.00 03/13/2013 06/25/2014 11:02:00 AM +0000 32 0 0 0 2014-06-25 11:02:00
2013-02-15 12:42:00 8AB1723 10 14 HYUND MD 900 CHARLES ST 18 All Other Parking Meter Violations $32.00 2013-02-15 12:42:00 ... 0 $32.00 $165.00 03/13/2013 08/26/2014 11:02:00 AM +0000 32 32 165 197 2014-08-26 11:02:00
2013-02-16 13:42:00 XAR7025 12 13 VOLKS VA 1000 CHARLES ST 18 All Other Parking Meter Violations $32.00 2013-02-16 13:42:00 ... 0 $32.00 $300.00 07/01/2013 01/09/2015 12:02:00 PM +0000 32 32 300 332 2015-01-09 12:02:00
2013-02-16 13:49:00 3AH9920 06 13 JEEP MD 1000 CHARLES ST 18 All Other Parking Meter Violations $32.00 2013-02-16 13:49:00 ... 0 $0.00 $0.00 03/13/2013 01/23/2014 12:02:00 PM +0000 32 0 0 0 2014-01-23 12:02:00
2013-02-18 09:11:00 1AT0603 07 14 FORD MD 1100 CHARLES ST 18 All Other Parking Meter Violations $32.00 2013-02-18 09:11:00 ... 0 $32.00 $325.00 03/13/2013 10/09/2014 11:02:00 AM +0000 32 32 325 357 2014-10-09 11:02:00
2013-02-19 21:41:00 9BEA59 09 14 AUDI MD 1300 CHARLES ST 16 In Transit Zone/Stop $77.00 2013-02-19 21:41:00 ... 0 $0.00 $0.00 03/13/2013 05/07/2013 05:41:00 PM +0000 77 0 0 0 2013-05-07 17:41:00
2013-02-20 11:47:00 T670730T 03 13 TOYOT MD 1000 CHARLES ST 18 All Other Parking Meter Violations $32.00 2013-02-20 11:47:00 ... 0 $32.00 $0.00 0 05/07/2013 05:41:00 PM +0000 32 32