<jupyter_start><jupyter_text>Section 1: Business Understanding  Question 1: How long does it take to deliver the shipments? Question 2: When are the shipments tendered? Question 3: How far do the shipments travel? Question 4: How many stops do the shipments make till final delivery?<jupyter_code>### Consistent use of df instead of df and inpDf
### Kernel: pipy335
import seaborn as sns
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt<jupyter_output><empty_output><jupyter_text>snsPlot is a wrapper function to speed up Seaborn category plots. This is accomplished by including settings commonly within the function.  The common settings are figure size, grid style, rotation of x-axis labels, position of the legend and title.  Highly recommend creating wrapper functions that contain personal preferences to speed up charting<jupyter_code>def snsPlot(chartType, data, title, x = None, y = None, hue = None, plotCount = 1, order = False):
    '''
    Creates standard plot using seaborn library
        
        Parameters:
                chartType (str): Standard seaborn category plot type. Allowed values are: bar, count, violin, box
                data (Dataframe): Pandas dataframe with input data
                title (str): Title for the plot
                x (str): column name from input dataframe (data) that will be used as 'x' axis
                y (str): column name from input dataframe (data) that will be used as 'y' axis
                hue (str): column name from input dataframe (data) that will be used as hue
                order (boolean): Boolean flag to indicate if the 'x' axis has to be ordered based on the 'y' axis values

    '''
    orderIndex = None
    if (y != None) & (order == True):
        orderIndex = data.groupby(by = [x])[y].mean().sort_values(ascending = False).index
    elif order:
        orderIndex = data[x].value_counts().sort_values(ascending = False).index
    plt.figure(figsize = (10,6))
    fGrid = sns.catplot(data = data, x = x, y = y, hue = hue, kind = chartType, height = 6, aspect = 1.52, order = orderIndex)
    ax = fGrid.axes[0,0]
    ax.grid(linestyle='-', linewidth='0.5', color='red')
    #ax.set_xlim(left = 0, right = 16)
    #ax.xaxis.set_major_locator(plt.MultipleLocator(10))
    #ax.yaxis.set_major_locator(plt.MultipleLocator(200))
    plt.xticks(rotation=45)
    if hue: sns.move_legend(fGrid, loc = 'upper right', bbox_to_anchor=(0.78, 0.95))
    fGrid.legend_out = False
    ax.set_title(title)<jupyter_output><empty_output><jupyter_text>Section 2: Data Understanding<jupyter_code>file1 = "/data2/home/prasannaiyer/Projects/TT_Fastai/Dataset/OTD_2019_PU.csv"
inpDf = pd.read_csv(file1)
#inpDf = inpDf[(inpDf['Days Late']<20)&((inpDf['Location Type']=='Plant')\
 #   |(inpDf['Location Type']=='Port')|(inpDf['Location Type']=='Keen'))]
inpDf = inpDf[((inpDf['Location Type']=='Plant')|(inpDf['Location Type']=='Port')|(inpDf['Location Type']=='Keen'))]
inp_shape = inpDf.shape
'Input data has {} rows and {} features'.format(inp_shape[0], inp_shape[1])
null_columns = inpDf.columns[inpDf.isnull().sum()!=0]
print('The following columns have null values:')
i = 1
for columns in null_columns:
    print(str(i) + ')  ' + columns)
    i += 1
inpDf.describe()<jupyter_output><empty_output><jupyter_text>Section 3: Data Preparation<jupyter_code>inpDf['Delivery_Date'] = pd.to_datetime(inpDf['Shipment End Date'])
inpDf['Pickup_Date'] = pd.to_datetime(inpDf['First shipped date (first YT26 action) Date'])
#inpDf['OutputTransitTime'] = (inpDf['Delivery_Date']-inpDf['Pickup_Date']).dt.days
inpDf.rename(columns = {'Shipment Secure Resources Upd Dt':'Tender_Date'},inplace = True)
inpDf['Tender_Date'] = pd.to_datetime(inpDf['Tender_Date'])
inpDf['OD'] = [1 if OD > 0 else 0 for OD in inpDf['Shipment OD Day']]<jupyter_output><empty_output><jupyter_text>For analysis, keep features that are available prior to the delivery of the shipment and drop the features that are pertaining to delivery<jupyter_code>inpDf.drop(['Shipment GID', 'Delivery Status','Shipment Source Location GID',\
    'Shipment Source Province Code','Shipment Destination Location GID',\
        'Shipment Destination Location Name', 'Shipment Destination City',\
            'Shipment Enroute Status Upd Dt','Vehicle Outbound Delivery tendered and accepted Date',\
                'First shipped date (first YT26 action) Date', 'Shipment End Date',\
                    'Expected Days to Deliver', 'Days Late','Year',\
                        'Month','Shipment OD Day','Pickup_Date','Delivery_Date'],\
                            inplace = True,axis=1)<jupyter_output><empty_output><jupyter_text>Section 6: Evaluation  Question 1: How long does it take to deliver the shipments? Actual Days: Based on describe and kde plot  There are outlier values. Based on domain knowledge of shipment profile and distance covered per day, Actual Days > 15 calendar days can be considered as outliers  Also, the outliers predominantly appear in the plant locations. Further investigation of the process is recommended to identify the breakdowns that are resulting in meaningless transit time<jupyter_code>inpDf['Actual Days'].describe()<jupyter_output><empty_output><jupyter_text>Chart 1: Below KDE plot of transit time shows that 90% of the shipments are being delivered in 10 days or less<jupyter_code>fig = plt.figure(figsize = (10, 6))
ax = sns.kdeplot(inpDf['Actual Days'], color='g', shade = True, cumulative = True)
#ax = sns.kdeplot(data = inpDf['Actual Days'], cumulative = True)
ax.grid(linestyle='-', linewidth='0.5', color='red')
ax.xaxis.set_major_locator(plt.MultipleLocator(10))
ax.yaxis.set_major_locator(plt.MultipleLocator(0.05))
ax.set_title('Chart 1: Distribution of Transit Time - KDE plot')
plt.xticks(rotation=45)<jupyter_output><empty_output><jupyter_text>Charts 2 & 3: The plots below show that there are outlier transit time values across all location types. These values can be removed prior to further analysis. In addition, deeper investigation is recommended to determine the root cause of these outlier values<jupyter_code>fig = plt.figure(figsize = (20, 6))
fig.add_subplot(1,2,1)
ax = sns.kdeplot(inpDf['Actual Days'], hue = inpDf['Location Type'], color='g', shade = True, cumulative = True)
#ax = sns.kdeplot(data = inpDf['Actual Days'], cumulative = True)
ax.grid(linestyle='-', linewidth='0.5', color='red')
ax.xaxis.set_major_locator(plt.MultipleLocator(10))
ax.yaxis.set_major_locator(plt.MultipleLocator(0.05))
plt.xticks(rotation=45)
ax.set_title('Chart 2: DISTRIBUTION OF TRANSIT TIME (ACTUAL DAYS) - LOCATION TYPE')
fig.add_subplot(1,2,2)
ax = sns.kdeplot(inpDf[inpDf['Actual Days']>20]['Actual Days'], hue = inpDf['Location Type'], color='g', shade = True, cumulative = True)
#ax = sns.kdeplot(data = inpDf['Actual Days'], cumulative = True)
ax.grid(linestyle='-', linewidth='0.5', color='red')
ax.set_xlim(left = 20, right = 400)
ax.xaxis.set_major_locator(plt.MultipleLocator(10))
ax.yaxis.set_major_locator(plt.MultipleLocator(0.05))
plt.xticks(rotation=45)
ax.set_title('Chart 3: DISTRIBUTION OF TRANSIT TIME (ACTUAL DAYS) LOCATION TYPE - OUTLIERS')

df = inpDf.loc[(inpDf['Actual Days']<=15) & (inpDf['Actual Days']>0),:]<jupyter_output><empty_output><jupyter_text>Chart 4: From the below box plot, median transit time = 5 days<jupyter_code>snsPlot('box', data = df, y = 'Actual Days', title = 'Chart 4: Transit Time Plot')<jupyter_output><empty_output><jupyter_text>Chart 5: The count of shipments with transit time > 8 days is low and exceptional<jupyter_code>fig = plt.figure(figsize = (10, 6))
ax = sns.kdeplot(df['Actual Days'], color='g', shade = True, cumulative = False)
#ax = sns.kdeplot(data = inpDf['Actual Days'], cumulative = True)
ax.grid(linestyle='-', linewidth='0.5', color='red')
ax.xaxis.set_major_locator(plt.MultipleLocator(2))
ax.yaxis.set_major_locator(plt.MultipleLocator(0.05))
ax.set_title('Chart 5: Transit Time Distribution')
plt.xticks(rotation=45)<jupyter_output><empty_output><jupyter_text>Chart 6: The KDE and violin plots show distribution of transit time after removal of outliers. 95% of the shipments are delivered in 12 days or less.<jupyter_code>fig = plt.figure(figsize = (10, 6))
ax = sns.kdeplot(df['Actual Days'], color='g', shade = True, cumulative = True)
#ax = sns.kdeplot(data = inpDf['Actual Days'], cumulative = True)
ax.grid(linestyle='-', linewidth='0.5', color='red')
ax.xaxis.set_major_locator(plt.MultipleLocator(2))
ax.yaxis.set_major_locator(plt.MultipleLocator(0.05))
ax.set_title('Chart 6: Transit Time Distribution')
plt.xticks(rotation=45)<jupyter_output><empty_output><jupyter_text>Chart 7: Based on the violin plot, count of shipments starts decreasing beyond transit time of 8 days<jupyter_code>snsPlot('violin', data = df,  y = 'Actual Days', title = 'Chart 7: Transit Time Plot')<jupyter_output><empty_output><jupyter_text>Charts 8: Distribution of transit time by location type: Plant & ports have similar distribution of transit time -- Min, mean, median, 25th & 75th percentile<jupyter_code>snsPlot('box', data = df, x = 'Location Type', y = 'Actual Days', title = 'Chart 8: Transit Time Plot')<jupyter_output><empty_output><jupyter_text>Chart 9: Shipments from Keen locations have a shorter transit time compared to plant and port shipments<jupyter_code>plt.figure(figsize = (10, 6))
#df = inpDf.loc[inpDf['Actual Days']<16 ,:]
ax = sns.kdeplot(df['Actual Days'], hue = df['Location Type'], color='g', shade = True, cumulative = True)
#ax = sns.kdeplot(data = inpDf['Actual Days'], cumulative = True)
ax.grid(linestyle='-', linewidth='0.5', color='red')
ax.set_xlim(left = 0, right = 16)
#ax.xaxis.set_major_locator(plt.MultipleLocator(10))
ax.yaxis.set_major_locator(plt.MultipleLocator(0.05))
plt.xticks(rotation=45)
sns.move_legend(ax, loc = 'upper left')
ax.set_title('Chart 9: DISTRIBUTION OF TRANSIT TIME (ACTUAL DAYS) LOCATION TYPE - WITHOUT OUTLIERS')<jupyter_output><empty_output><jupyter_text>Charts: 10, 11 & 12 Analysis of shipment volume by transit time: Plant & port shipments have maximum volume for transit time of 6 days Keen shipments have maximum volume for transit time of 2 days<jupyter_code>j = 9
for locType in df['Location Type'].unique():
    j += 1
    snsPlot('count', data = df[df['Location Type']== locType], title = ('Chart ' + str(j) + ' Shipment Volume by Transit Time - ' + locType) , x = 'Actual Days', hue = 'OD')<jupyter_output><empty_output><jupyter_text>One of the important steps in data exploration is to look for null values and replace them appropriately [delete or impute].  In this dataset there are not any null values<jupyter_code>df.isnull().sum().sort_values(ascending = False)<jupyter_output><empty_output><jupyter_text>Question 2: When are the shipments tendered? Analysis of Shipment Tenders  Across all locations 6.3% more shipments are tendered on Mondays compared to other days of the week. This effect is prominent among the plant locations. However, for non-plant locations, shipments are tendered in a more linear fashion throughout the week. Additional features can be created from date features and insights can be gained from these new features<jupyter_code>df['Tender_Day']=df['Tender_Date'].dt.day
df['Tender_DoW'] = df['Tender_Date'].dt.dayofweek
df['Tender_Month'] = df['Tender_Date'].dt.month<jupyter_output>/data2/prasannaiyer/envs/pipy335/lib/python3.7/site-packages/ipykernel_launcher.py: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 caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  """Entry point for launching an IPython kernel.
/data2/prasannaiyer/envs/pipy335/lib/python3.7/site-packages/ipykernel_launcher.py: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 caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  
/data2/prasannaiyer/envs/pipy335/lib/python3.7/site-packages/ipykernel_launcher.py:3: 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[...]<jupyter_text>Plants: 12.5% more shipments are tendered on Mondays compared to other days of the week. This is important as shipments tendered on Monday are more likely to be delivered within the week Non Plant Locations: The opposite trend is observed. 15% - 20% more shipments are tendered between Monday & Friday<jupyter_code>tenderDf = pd.DataFrame()
tenderDf['Location Type'] =''
tenderDf['Mon_Shipment_Count'] = ''
tenderDf['Non_Mon_Shipment_Count'] = ''
tenderDf['Avg_By_Day'] = ''
#tenderDf.loc[0] = ['Port',allMonShipments,allMonNonPlant]
i = 0
for locType in ['Plant', 'Port', 'Keen']:
    monShipments = df[(df['Tender_DoW'] == 0) & (df['Location Type'] == locType)]['Tender_DoW'].count().astype(int)
    nonMonShipments = int(df[(df['Tender_DoW'].isin([1,2,3,4])) & (df['Location Type'] == locType)]['Tender_DoW'].value_counts().mean())
    avgByDay = int(df[(df['Tender_DoW'].isin([0,1,2,3,4])) & (df['Location Type'] == locType)]['Tender_DoW'].value_counts().mean())
    tenderDf.loc[i] = [locType, monShipments, nonMonShipments, avgByDay]
    i += 1
display(tenderDf)
tenderDf.sum()<jupyter_output><empty_output><jupyter_text>Chart 13: Based on the count plot shown below: Plants: More shipments are tendered on Mondays compared to other days of the week Ports/Keen: Linear volume observed across days of the week<jupyter_code>snsPlot('count', df, x = 'Tender_DoW', hue = 'Location Type', title = 'Chart 13: Shipment Count by Tender DoW', order = False)<jupyter_output><empty_output><jupyter_text>Chart 14: As shown the bar chart below, shipments tendered mid or later in the week have a longer transit time.<jupyter_code>snsPlot(chartType = 'bar', data = df, x = 'Tender_DoW', y = 'Actual Days', title = 'Chart 14: Transit Time vs. Tender Day_of_Week')<jupyter_output><empty_output><jupyter_text>Question 3: How far do the shipments travel? Analysis of Shipment Distance Charts 15 & 16: Based on the distribution of distance, shipments with distance > 2500 miles seem like outliers.  After eliminating the outliers, average distance of the shipments = 820 miles  Median distance of the shipments = 742 miles<jupyter_code>fig = plt.figure(figsize=(20,6))
fig.add_subplot(1,2,1)
ax = sns.kdeplot(df['Shipment Loaded Distance'], color='g', shade = True, cumulative = True)
ax.grid(linestyle='-', linewidth='0.5', color='red')
#ax.set_xlim(left = 0, right = 16)
ax.xaxis.set_major_locator(plt.MultipleLocator(200))
ax.yaxis.set_major_locator(plt.MultipleLocator(0.05))
plt.xticks(rotation=45)
ax.set_title('Chart 15: DISTRIBUTION OF SHIPMENT DISTANCE')
fig.add_subplot(1,2,2)
ax = sns.kdeplot(df['Shipment Loaded Distance'], hue = df['Location Type'], color='g', shade = True, cumulative = True)
ax.grid(linestyle='-', linewidth='0.5', color='red')
ax.yaxis.set_major_locator(plt.MultipleLocator(0.05))
ax.xaxis.set_major_locator(plt.MultipleLocator(200))
plt.xticks(rotation=45)
ax.set_title('Chart 16: DISTRIBUTION OF SHIPMENT DISTANCE BY LOCATION TYPE')
#snsPlot('count', data = inpDf[inpDf['Location Type']=='Plant'], x = 'Shipment Source City', title = 'Shipment Count by Plant', order = True)<jupyter_output><empty_output><jupyter_text>Chart 17: The box and violin plots below show that distance percentiles and distribution<jupyter_code>snsPlot('box',df,"Chart 17: Distance Plot", y = 'Shipment Loaded Distance', order = False)<jupyter_output><empty_output><jupyter_text>Chart 18: 96% of the shipments travel less than 2000 miles<jupyter_code>snsPlot('violin',df,"Chart 18: Distance Plot", y = 'Shipment Loaded Distance', order = False)<jupyter_output><empty_output><jupyter_text>Chart 19: The KDE plot of the distance shows that 95% of the shipments travel a distance of 1900 miles or less<jupyter_code>fig = plt.figure(figsize = (10, 6))
ax = sns.kdeplot(df['Shipment Loaded Distance'], color='g', shade = True, cumulative = True)
#ax = sns.kdeplot(data = inpDf['Actual Days'], cumulative = True)
ax.grid(linestyle='-', linewidth='0.5', color='red')
ax.xaxis.set_major_locator(plt.MultipleLocator(200))
ax.yaxis.set_major_locator(plt.MultipleLocator(0.05))
ax.set_title('Chart 19: Distance Plot')
plt.xticks(rotation=45)<jupyter_output><empty_output><jupyter_text>The tabular summary as well as the box plot of the distance show that plant shipments travel a longer distance compared to port & keen shipments<jupyter_code>distanceDf = pd.DataFrame()
distanceDf['Location Type'] =''
distanceDf['Avg_Distance'] = ''
distanceDf['Median_Distance'] = ''
distanceDf['Shipment_Count'] =''
i = 0
for locType in ['Plant', 'Port', 'Keen']:
    avgDistance = int(df[(df['Shipment Loaded Distance'] < 2501) & (df['Location Type'] == locType)]['Shipment Loaded Distance'].mean())
    medianDistance = int(df[(df['Shipment Loaded Distance'] < 2501) & (df['Location Type'] == locType)]['Shipment Loaded Distance'].median())
    shipmentCount = int(df[(df['Shipment Loaded Distance'] < 2501) & (df['Location Type'] == locType)]['Location Type'].count())
    distanceDf.loc[i] = [locType, avgDistance, medianDistance, shipmentCount]
    i += 1
avgDistance = int(df[(df['Shipment Loaded Distance'] < 2501)]['Shipment Loaded Distance'].mean())
medianDistance = int(df[df['Shipment Loaded Distance'] < 2501]['Shipment Loaded Distance'].median())
shipmentCount = int(df[(df['Shipment Loaded Distance'] < 2501)]['Location Type'].count())
distanceDf.loc[i] = ['All', avgDistance, medianDistance, shipmentCount]
display(distanceDf)<jupyter_output><empty_output><jupyter_text>Chart 20: Shipments originating from plant locations travel 8.5% greater distance than the overall distance average. It is important to note that 67% of all shipments originate from plant. Plants shipments travel 28% farther than port shipments<jupyter_code>snsPlot('box',df,"Chart 20: Distance Plot",x = 'Location Type', y = 'Shipment Loaded Distance', order = True)<jupyter_output><empty_output><jupyter_text>Charts 21 & 22: The bar plots below show that: Distance travelled by Laredo shipments is longer than other plant locations New Holland is the location with the most shipments among plants<jupyter_code>fig = plt.figure(figsize=(20,6))
fig.add_subplot(1,2,1)
#snsPlot('bar', data = df[df['Location Type']=='Plant'], x = 'Shipment Source City', \
 #   y = 'Shipment Loaded Distance', title = 'Avg. Shipment Distance by Plant', order = True)
order = df[df['Location Type']=='Plant'].groupby(by = 'Shipment Source City')['Shipment Loaded Distance'].mean().sort_values(ascending = False).index
ax = sns.barplot(data = df[df['Location Type']=='Plant'], x = 'Shipment Source City', y = 'Shipment Loaded Distance', order = order)
ax.grid(linestyle='-', linewidth='0.5', color='red')
#ax.set_xlim(left = 0, right = 16)
#ax.xaxis.set_major_locator(plt.MultipleLocator(10))
#ax.yaxis.set_major_locator(plt.MultipleLocator(200))
plt.xticks(rotation=45)
#sns.move_legend(ax, loc = 'upper right')
ax.set_title('Chart 21: Avg. Shipment Distance by Plant')
fig.add_subplot(1,2,2)
order = df[df['Location Type']=='Plant']['Shipment Source City'].value_counts().sort_values(ascending = False).index
ax = sns.countplot(data = df[df['Location Type']=='Plant'], x = 'Shipment Source City', order = order)
ax.grid(linestyle='-', linewidth='0.5', color='red')
plt.xticks(rotation=45)
ax.set_title('Chart 22: Shipment Count by Plant')
#snsPlot('count', data = df[df['Location Type']=='Plant'], x = 'Shipment Source City', title = 'Shipment Count by Plant', order = True)<jupyter_output><empty_output><jupyter_text>Chart 23: From the two bar charts below, it can be observed that as distance increases, the transit time also increases<jupyter_code>snsPlot(chartType = 'bar', data = df, x = 'Actual Days', y = 'Shipment Loaded Distance', title = 'Chart 23: Transit Time vs. Shipment Distance')<jupyter_output><empty_output><jupyter_text>Question 4: How many stops do the shipments make till final delivery?  Analysis of STOPS PER SHIPMENT Average stops per shipment = 2.8 Port and Keen shipments have a greater proportion of multi-stop shipments (> 2 stops) compared to the plant locations. This is understandable, as Port and Keen locations ship smaller products compared to the plants.<jupyter_code>df = df[df['Shipment Loaded Distance']<2501]
df['Shipment Num Stops'].describe()<jupyter_output><empty_output><jupyter_text>Chart 24: Based on the box plot of the number of stops: 75% of the shipments have 3 stops or less<jupyter_code>snsPlot(chartType = 'box', data = df, y = 'Shipment Num Stops', title = 'Chart 24: Shipment Count by Shipment Stops' )<jupyter_output><empty_output><jupyter_text>Chart 26: Based on the count plots shown below, most number of shipments have 2 stops<jupyter_code>snsPlot(chartType = 'count', data = df, x = 'Shipment Num Stops', title = 'Chart 25: Shipment Count by Shipment Stops' )<jupyter_output><empty_output><jupyter_text>Chart 26: Also across location types, maximum number of shipments have 2 stops<jupyter_code>snsPlot(chartType = 'count', data = df, x = 'Shipment Num Stops', title = 'Chart 26: Shipment Count by Shipment Stops', hue = 'Location Type' )<jupyter_output><empty_output><jupyter_text>Chart 27: Based on the bar chart below, shipments from keen locations have more stops compared to plant or port locations.<jupyter_code>snsPlot('bar', df, 'Chart 27: Avg. Shipment Stops by Location Type', x = 'Location Type', y = 'Shipment Num Stops', order = True)<jupyter_output><empty_output><jupyter_text>Charts 28 & 29: The three plots below show -- Shipment stops vs. Shipment distance. Based on the plots, as shipment stops increase, shipment distance also increases This trend is noticed across all location types<jupyter_code>fig = plt.figure(figsize=(20,6))
fig.add_subplot(1,2,1)
#snsPlot('bar', data = df[df['Location Type']=='Plant'], x = 'Shipment Source City', \
 #   y = 'Shipment Loaded Distance', title = 'Avg. Shipment Distance by Plant', order = True)
order = df.groupby(by = 'Shipment Num Stops')['Shipment Loaded Distance'].mean().sort_values(ascending = False).index
ax = sns.barplot(data = df, x = 'Shipment Num Stops', y = 'Shipment Loaded Distance', order = order)
ax.grid(linestyle='-', linewidth='0.5', color='red')
#ax.set_xlim(left = 0, right = 16)
#ax.xaxis.set_major_locator(plt.MultipleLocator(10))
#ax.yaxis.set_major_locator(plt.MultipleLocator(200))
plt.xticks(rotation=45)
#sns.move_legend(ax, loc = 'upper right')
ax.set_title('Chart 28: Shipment Stops vs. Distance')
fig.add_subplot(1,2,2)
order = df['Shipment Num Stops'].value_counts().sort_values(ascending = False).index
ax = sns.countplot(data = df, x = 'Shipment Num Stops', order = order)
ax.grid(linestyle='-', linewidth='0.5', color='red')
plt.xticks(rotation=45)
ax.set_title('Chart 29: Shipment Count by Stop Count')
#sns.move_legend(ax, loc = 'upper right')
#snsPlot('count', data = df[df['Location Type']=='Plant'], x = 'Shipment Source City', title = 'Shipment Count by Plant', order = True)<jupyter_output><empty_output><jupyter_text>Charts 30 & 31: Also across location types, shipment distance increases with shipment stops<jupyter_code>fig = plt.figure(figsize=(20,6))
fig.add_subplot(1,2,1)
#snsPlot('bar', data = df[df['Location Type']=='Plant'], x = 'Shipment Source City', \
 #   y = 'Shipment Loaded Distance', title = 'Avg. Shipment Distance by Plant', order = True)
order = df.groupby(by = 'Shipment Num Stops')['Shipment Loaded Distance'].mean().sort_values(ascending = False).index
ax = sns.barplot(data = df, x = 'Shipment Num Stops', y = 'Shipment Loaded Distance', hue = 'Location Type', order = order)
ax.grid(linestyle='-', linewidth='0.5', color='red')
#ax.set_xlim(left = 0, right = 16)
#ax.xaxis.set_major_locator(plt.MultipleLocator(10))
#ax.yaxis.set_major_locator(plt.MultipleLocator(200))
plt.xticks(rotation=45)
sns.move_legend(ax, loc = 'upper right')
ax.set_title('Chart 30: Avg. Stops per Shipment')
fig.add_subplot(1,2,2)
order = df['Shipment Num Stops'].value_counts().sort_values(ascending = False).index
ax = sns.countplot(data = df, x = 'Shipment Num Stops', hue = 'Location Type', order = order)
ax.grid(linestyle='-', linewidth='0.5', color='red')
plt.xticks(rotation=45)
ax.set_title('Chart 31: Shipment Count by Stop Count')
sns.move_legend(ax, loc = 'upper right')
#snsPlot('count', data = df[df['Location Type']=='Plant'], x = 'Shipment Source City', title = 'Shipment Count by Plant', order = True)<jupyter_output><empty_output><jupyter_text>Charts 32 & 33: The KDE plots below show that 95% of the shipments have 5 stops or less<jupyter_code>fig = plt.figure(figsize=(20,6))
fig.add_subplot(1,2,1)
ax = sns.kdeplot(df['Shipment Num Stops'], color='g', shade = True, cumulative = True)
ax.grid(linestyle='-', linewidth='0.5', color='red')
#ax.set_xlim(left = 0, right = 16)
ax.xaxis.set_major_locator(plt.MultipleLocator(1))
ax.yaxis.set_major_locator(plt.MultipleLocator(0.05))
plt.xticks(rotation=45)
ax.set_title('Chart 32: DISTRIBUTION OF SHIPMENT STOPS')
fig.add_subplot(1,2,2)
ax = sns.kdeplot(df['Shipment Num Stops'], hue = df['Location Type'], color='g', shade = True, cumulative = True)
ax.grid(linestyle='-', linewidth='0.5', color='red')
ax.yaxis.set_major_locator(plt.MultipleLocator(0.05))
ax.xaxis.set_major_locator(plt.MultipleLocator(1))
plt.xticks(rotation=45)
ax.set_title('Chart 33: DISTRIBUTION OF SHIPMENT STOPS BY LOCATION TYPE')
#snsPlot('count', data = inpDf[inpDf['Location Type']=='Plant'], x = 'Shipment Source City', title = 'Shipment Count by Plant', order = True)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13469956998411653, 'fraction_numerical': 0.020997171967613217, 'mean_word_length': 5.931793770139635, 'pattern_counts': {'":': 0, '<': 154, '<?xml version=': 0, '>': 151, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '36', 'dir': 'jupyter-structured-clean-dedup', 'id': '123648', 'license': 'Apache-2.0', 'n_tokens_mistral': 9217, 'n_tokens_neox': 8610, 'n_words': 2443, 'path': 'TT_EDA.ipynb', 'repo_name': 'prasiyer/ML_Logistics', 'size': '25813'}