{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "8a74ee46",
   "metadata": {},
   "source": [
    "# Percentiles\n",
    "\n",
    "A percentile locates a value in ordered numerical data. A delivery manager might use a high percentile of delivery times to describe a service target; the median describes a central delivery time. These summaries answer different business questions.\n",
    "\n",
    "With ties or a small dataset, more than one percentile convention is possible. This chapter uses **NumPy's nearest convention** for percentile calculations and confidence-interval endpoints. It selects an observed value near a position in the sorted list. A percentile is not a guarantee that exactly the stated fraction lies strictly below it.\n",
    "\n",
    "For an ordinary **median**, use `np.median(values)` or `series.median()`: with an even number of observations, average the two middle values. A nearest-method 50th percentile can differ from that ordinary median. You will see that distinction below.\n",
    "\n",
    "Run the demonstration cells in order. Each Interactive Exercise includes independent setup.\n",
    "\n",
    "```{index} Percentile\n",
    "```\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "6c8fc1c7",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-31T06:01:24.201136Z",
     "iopub.status.busy": "2026-08-31T06:01:24.200926Z",
     "iopub.status.idle": "2026-08-31T06:01:24.567170Z",
     "shell.execute_reply": "2026-08-31T06:01:24.566889Z"
    },
    "tags": [
     "hide-input",
     "thebe-init",
     "runnable"
    ]
   },
   "outputs": [],
   "source": [
    "path_data = '../../data/'\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "plt.style.use('fivethirtyeight')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "abde1a7d",
   "metadata": {},
   "source": [
    "```{contents}\n",
    ":local:\n",
    ":depth: 2\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f8a8182d",
   "metadata": {},
   "source": [
    "<!-- moved-from-landing: 1100-estimation -->\n",
    "\n",
    "## Estimation Prelude\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ce88532c",
   "metadata": {},
   "source": [
    "In the previous chapter, we began to develop ways of inferential thinking. In particular, we learned how to use data to decide between two hypotheses about the world. But often we just want to know **how big** something is. \n",
    "\n",
    "For example, during an election year, we may want to know the percentage of voters who favor a particular candidate. To assess the current state of the economy, we might be interested in the median annual income of households in the United States.\n",
    "\n",
    "In this chapter, we will develop a way to **estimate** an **unknown parameter**. Remember that a parameter is a numerical value associated with a population.  \n",
    "\n",
    "To figure out the value of a parameter, we need data. If we have the relevant data for the entire population, we can simply calculate the parameter. \n",
    "\n",
    "However, if the population is very large – for example, if it comprises all the households in the United States – then gathering data from the entire population might be too expensive and time-consuming. In such situations, data scientists rely on **random sampling** from the population. \n",
    "\n",
    "This raises a question of inference: How can justifiable conclusions be drawn about the unknown parameter based on the data from the random sample? We will answer this question by using inferential thinking.\n",
    "\n",
    "A statistic based on a random sample can be a reasonable estimate of an unknown parameter in the population. For example, you might want to use the **median annual income of sampled households as an estimate of the median annual income of all households** in the U.S.\n",
    "\n",
    "However, the value of any statistic depends on the sample, which is based on random draws. So every time data scientists come up with an estimate based on a random sample, they are faced with a question:\n",
    "\n",
    "**\"How different could this estimate have been, if the sample had come out differently?\"**\n",
    "\n",
    "In this chapter, you will learn one way of answering this question. The answer will provide you with the tools to estimate a numerical parameter and quantify the error in your estimate.\n",
    "We will start with a preliminary about percentiles. The most famous percentile is the median, often used in summaries of income data. Other percentiles will be important in the method of estimation that we are about to develop. So we will start by defining percentiles carefully.\n",
    "\n",
    "For a store, the population might be all completed orders in a specified month, the parameter their mean value, and the estimate the mean of a random sample. Specify the population and measurement period before sampling. An estimate of a monthly mean does not describe every individual order.\n",
    "\n",
    "The percentile calculations below first summarize observed data. Later, the same calculation selects endpoints from a distribution of **bootstrap statistics**, rather than from the individual observations.\n",
    "\n",
    "```{index} Parameter\n",
    "```\n",
    "\n",
    "```{index} Statistic\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4c7e219a",
   "metadata": {},
   "source": [
    "## A Numerical Example\n",
    "\n",
    "Consider the following five continent areas, rounded to the nearest million square miles. A percentile calculation first sorts the values. Under the nearest convention, the 80th percentile selects the value nearest position `(5 - 1) * 80 / 100 = 3.2`, counting the first sorted position as zero. Position three contains 12.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "a9e02ba0",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-31T06:01:24.568544Z",
     "iopub.status.busy": "2026-08-31T06:01:24.568444Z",
     "iopub.status.idle": "2026-08-31T06:01:24.569882Z",
     "shell.execute_reply": "2026-08-31T06:01:24.569733Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "sizes = np.array([12, 17, 6, 9, 7])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f5401ace",
   "metadata": {},
   "source": [
    "Sort the data before interpreting a percentile. The zero-based positions will be zero through four.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "3f667fd7",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-31T06:01:24.570830Z",
     "iopub.status.busy": "2026-08-31T06:01:24.570774Z",
     "iopub.status.idle": "2026-08-31T06:01:24.573040Z",
     "shell.execute_reply": "2026-08-31T06:01:24.572874Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "output_type": "execute_result",
     "metadata": {},
     "data": {
      "text/plain": "array([ 6,  7,  9, 12, 17])"
     },
     "execution_count": 3
    }
   ],
   "source": [
    "np.sort(sizes)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0b003afc",
   "metadata": {},
   "source": [
    "The sorted values are `[6, 7, 9, 12, 17]`. The nearest position to 3.2 is three, so the nearest-method 80th percentile is 12. Four of these five values, or 80%, are less than or equal to 12.\n",
    "\n",
    "For the 70th percentile, the position is `(5 - 1) * 70 / 100 = 2.8`. Its nearest integer is also three, so the answer is again 12. With a small dataset, different percentile requests can select the same observed value.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3f68b547",
   "metadata": {},
   "source": [
    "## The `percentile` function\n",
    "\n",
    "The pattern is `np.percentile(values, percentage, method='nearest')`. The **data come first**, followed by a percentage from zero to 100 inclusive. You can pass a list of percentages to request several values at once.\n",
    "\n",
    "NumPy's default method is `linear`, which can interpolate between observations. This chapter explicitly requests `nearest` to keep the convention visible. Other methods, such as `inverted_cdf`, implement different rules; they are not interchangeable on small datasets. See the [NumPy percentile documentation](https://numpy.org/doc/stable/reference/generated/numpy.percentile.html).\n",
    "\n",
    "```text\n",
    "np.percentile(values, percentage, method='nearest')\n",
    "np.percentile(values, [25, 50, 75], method='nearest')\n",
    "```\n",
    "\n",
    "These are syntax patterns: replace `values` with your array or Series and `percentage` with the requested percentage. The next cell applies the pattern to the continent data.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "b2a44c6a",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-31T06:01:24.573969Z",
     "iopub.status.busy": "2026-08-31T06:01:24.573919Z",
     "iopub.status.idle": "2026-08-31T06:01:24.575559Z",
     "shell.execute_reply": "2026-08-31T06:01:24.575373Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "output_type": "execute_result",
     "metadata": {},
     "data": {
      "text/plain": "np.int64(12)"
     },
     "execution_count": 4
    }
   ],
   "source": [
    "np.percentile(sizes, 70, method='nearest')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b47e2159",
   "metadata": {},
   "source": [
    "### The General Definition ###\n",
    "\n",
    "For this chapter's **nearest convention**, sort the `n` observations and calculate the zero-based position `j = (n - 1) * p / 100`. Select the observed value at the nearest integer position. At an exact halfway tie, NumPy rounds to the even index. The zero and 100th percentiles select the minimum and maximum, respectively.\n",
    "\n",
    "You can reproduce this indexing rule with `index = int(np.rint(j))`, then access `sorted_values[index]`. `np.rint` rounds to the nearest integer with the same even-index tie rule.\n",
    "\n",
    "A different, valid convention uses the one-based rank `ceil(n * p / 100)` for positive `p`. That is the inverse empirical-distribution convention, available as `method='inverted_cdf'`. It is **not** the nearest rule used here. For the homework order values, the two rules give different first and third quartiles, so always state the method used.\n",
    "\n",
    "For `[1, 2, 3, 4]`, the nearest-method 50th percentile selects index two, giving 3. The ordinary median averages 2 and 3, giving 2.5. Use the ordinary median consistently when the statistic being bootstrapped is called the sample median.\n",
    "\n",
    "```{index} Median\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "tags": [
     "thebe-interactive"
    ]
   },
   "outputs": [],
   "source": [
    "### Exercise: Compare Two Conventions\n",
    "# For these four values, compute the nearest-method 50th percentile and\n",
    "# the ordinary median. Print both and explain their difference in a comment.\n",
    "import numpy as np\n",
    "values = np.array([1, 2, 3, 4])\n",
    "### Your code starts here.\n",
    "\n",
    "### Your code ends here."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "tags": [
     "hide-input"
    ]
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "Nearest 50th percentile: 3\nOrdinary median: 2.5\n"
    }
   ],
   "source": [
    "### Solution\n",
    "import numpy as np\n",
    "values = np.array([1, 2, 3, 4])\n",
    "print('Nearest 50th percentile:', np.percentile(values, 50, method='nearest'))\n",
    "print('Ordinary median:', np.median(values))\n",
    "# Nearest selects one observed value; the median averages the middle two."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "864f1ce0",
   "metadata": {},
   "source": [
    "### Example ###\n",
    "The table `scores_and_sections` contains one row for each student in a class of 359 students. The columns are the student's discussion section and midterm score. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "c6358e32",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-31T06:01:24.576551Z",
     "iopub.status.busy": "2026-08-31T06:01:24.576497Z",
     "iopub.status.idle": "2026-08-31T06:01:24.583338Z",
     "shell.execute_reply": "2026-08-31T06:01:24.583161Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "output_type": "execute_result",
     "metadata": {},
     "data": {
      "text/plain": "     Section  Midterm\n0          1       22\n1          2       12\n2          2       23\n3          2       14\n4          1       20\n..       ...      ...\n354        5       24\n355        2       16\n356        2       17\n357       12       16\n358       10       14\n\n[359 rows x 2 columns]",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>Section</th>\n      <th>Midterm</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>1</td>\n      <td>22</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>2</td>\n      <td>12</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>2</td>\n      <td>23</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>2</td>\n      <td>14</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>1</td>\n      <td>20</td>\n    </tr>\n    <tr>\n      <th>...</th>\n      <td>...</td>\n      <td>...</td>\n    </tr>\n    <tr>\n      <th>354</th>\n      <td>5</td>\n      <td>24</td>\n    </tr>\n    <tr>\n      <th>355</th>\n      <td>2</td>\n      <td>16</td>\n    </tr>\n    <tr>\n      <th>356</th>\n      <td>2</td>\n      <td>17</td>\n    </tr>\n    <tr>\n      <th>357</th>\n      <td>12</td>\n      <td>16</td>\n    </tr>\n    <tr>\n      <th>358</th>\n      <td>10</td>\n      <td>14</td>\n    </tr>\n  </tbody>\n</table>\n<p>359 rows × 2 columns</p>\n</div>"
     },
     "execution_count": 7
    }
   ],
   "source": [
    "scores_and_sections = pd.read_csv(path_data + 'scores_by_section.csv')\n",
    "scores_and_sections"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "d4f569f6",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-31T06:01:24.584232Z",
     "iopub.status.busy": "2026-08-31T06:01:24.584186Z",
     "iopub.status.idle": "2026-08-31T06:01:24.633071Z",
     "shell.execute_reply": "2026-08-31T06:01:24.632876Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "output_type": "display_data",
     "metadata": {},
     "data": {
      "text/plain": "<Figure size 500x300 with 1 Axes>",
      "image/png": "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JMxFgBLDepi8KCUlxeVrLl68KKtXr1azHWLWQyIiIgqj4GDq1KkyceJEw2O//vqr1KlTx6vX33fffb6vHREREQVvcIC8AX3uACY08pRLgK6EKlWqSJcuXaRv377+rSkREREFV3AwYsQI9aW5/PLL1fwFy5YtC9S6ERERUShNvDRs2DApX768vWtDREREoRscDB8+3N41ISIioqDA8slERERkT8sBZGdny6effirLly+XvXv3yrlz51wmKSKBcfPmzf58HBEREQVzcHD27Fnp1KmTbNq0yasKiAgOiIiIKIyDA8yV8OOPP6rhit26dZNGjRpJiRIlJDqaPRVEREQRGRwsXLhQBQKYcfGGG26wd62IiIgo31i+zT927JhUqFCBgQEREVGYsRwcJCcnq0JIREREFF4sBwctW7aUHTt2qMREIiIiCh/R/hRBKlCggKqUmJWVZe9aERERUeglJP71119qroWRI0eq2RkffPBBufLKK9XoBVeuv/56qx9HREREwR4ctGnTxlG7AN0Lzz77rNvlsezJkyetfhwREREFe3CASZdY2IiIiCj8WA4Otm7dau+aEBERUVBgOUMiIiIyYHBARERE9s3KqM3MuGjRIlmzZo0cOnRILl68qEorazAT4/nz56Vp06acd4GIiCjcgwOMUnjooYdk165djpkZnZMUP/vsM5k+fbosWLBAbrzxRv/WloiIiALO8q38iRMnpEOHDrJz506pVauWKopUtWrVXMvde++9KnBYunSpv+tKREREwRwcvPnmm3L06FHp2rWrrF69WlVKLFmyZK7l6tevL4UKFZL169f7u65EREQUzMHB8uXLVfnkCRMmeKx3UKlSJVVRkYiIiMI4OEhJSZErrrhCLrvsMo/LoqQyEhWJiIgojIOD+Ph4SUtL8zo/oUiRIlY/ioiIiEIhOEDyIVoP/vnnH7fL7d+/X31dc801Vj+KiIiIQiE4uOOOOyQjI0PGjBnjchmMUsCETMhJwERNREREFMbBweOPPy5lypSRDz/8ULp37y6rVq2SS5cuqefQorBs2TJp27atGsKIhETUQyAiIqIwLoJUtGhRVeCoS5cusnjxYlmyZInjuTp16jhaDhBAzJkzRxITE+1ZYyIiIgoov+oZo/jRunXr5Omnn5YqVaqoYED7Klu2rPTv319++OEH5hsQERGFEL/nVkhKSpLn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twIRERGFZnDwyy+/yL333isVK1aUsmXLyq233ioLFizItdzGjRulVatWUr58eWnUqJF89NFHpu93/PhxqVy5skyaNCkP1p6IiCh0hERw8P3338vtt9+uLvwdOnSQhx9+WI4dO6a+v/32247lUlJSpGPHjurC36NHD7n88svliSeekIULF+Z6z6FDh0q5cuVk4MCBefzXEBERBbegzznIzMxUF/Do6GhZsmSJ1K5d23Fxv+WWW+Sll16Sdu3aqRaFefPmSVpamixevFgqVKggWVlZ0rhxY5k1a5bcfffdjvdctmyZLFq0SFauXCmxsUG/CYiIiPJUbCi0Guzbt08eeOABR2AARYsWlaeeekr69u0rc+fOlWHDhsmhQ4ekePHiKjCAmJgYqVWrlvz++++O1505c0YGDx4sjz32mNSvX1/yS7TkSNF48yz47JwoyZRoiY2Pkuio3MvEuHmtt58dbH+zJzH5uL38eX0wvpbby97tFcjPDsXXcnvZv73y45wdlZqamj9XCi+9+OKL8tprr8mMGTPknnvuMTyHroXq1avLDTfcoLoOsNzLL78sv/32m+oyyM7OVi0HaFWYP3++es3TTz+tWgw2bNgghQoVyqe/ioiIKHgFfc7Bnj171Pcrrrgi13OlSpWSwoULy969e9XvnTp1kvj4eGnTpo2MHDlS7rzzTtm1a5c89NBD6nnkLHzwwQfy+uuvMzAgIiIK1eAA3QBQpEgR0+cvu+wyxzJaC0GxYsVk5syZcvLkSXnrrbdUvkF6errKXUAAgVyFb775Ro1mSE5OloYNG6rWBCIiIgqBnANfNWvWTL799ttcj7/yyity4sQJGTdunBw4cEC6desmbdu2VY9//PHH6veffvrJka9AREQUqYK+5UBrMdBaB5ydPXvWZauC5o8//pA33nhDxo4dq1oK0KqQkJAgkydPlhtvvFENhyxQoIB6nIiIKNIFfXCg5RpouQfOCYnnzp2TqlWrunw9khJR6wBBwH333aceQx7ClVdeKYmJ/6shjO/4fefOnQH7O4iIiEJF0AcH119/vfq+atWqXM9p3QfaMmbeffddNZTRuRLipUuXcv0e5WIYCRERUSQJ+uAAd/woc/zFF1+oIYqa06dPq6GLGJ3QpUsX09eiYuKYMWPkmWeekUqVKjkex/DHHTt2qNwDwHf8jseJiIgiXdAHB6hg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"
     }
    }
   ],
   "source": [
    "from matplotlib.ticker import FuncFormatter\n",
    "\n",
    "fig, ax = plt.subplots(figsize=(5,3))\n",
    "\n",
    "ax.hist(\n",
    "    scores_and_sections['Midterm'], \n",
    "    bins = np.arange(-0.5, 25.6, 1), \n",
    "    density=True, \n",
    "    alpha=0.8, \n",
    "    ec='white')\n",
    "\n",
    "unit = ''\n",
    "y_label = 'Percent per ' + (unit if unit else 'unit')\n",
    "x_label = 'Midterm'\n",
    "\n",
    "plt.ylabel(y_label)\n",
    "plt.xlabel(x_label)\n",
    "y_vals = ax.get_yticks()\n",
    "# ax.set_yticklabels(['{:g}'.format(x * 100) for x in y_vals])\n",
    "ax.yaxis.set_major_formatter(FuncFormatter(lambda y, _: '{:.0f}%'.format(y*100)))\n",
    "\n",
    "plt.title('Distribution of Midterm Scores');\n",
    "# ax.set_title('Distribution of Midterm Scores')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b08af89a",
   "metadata": {},
   "source": [
    "What was the 85th percentile of the scores? To use the `percentile` function, create an array `scores` containing the midterm scores, and find the 85th percentile:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "33dc8442",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-31T06:01:24.634175Z",
     "iopub.status.busy": "2026-08-31T06:01:24.634107Z",
     "iopub.status.idle": "2026-08-31T06:01:24.636151Z",
     "shell.execute_reply": "2026-08-31T06:01:24.635961Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "output_type": "execute_result",
     "metadata": {},
     "data": {
      "text/plain": "0    22\n1    12\n2    23\n3    14\n4    20\nName: Midterm, dtype: int64"
     },
     "execution_count": 9
    }
   ],
   "source": [
    "scores = scores_and_sections.iloc[:,1]  ### select the second column of the DataFrame, \n",
    "                                        ### which contains the midterm scores.\n",
    "scores.head()    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "a07fa51a",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-31T06:01:24.637043Z",
     "iopub.status.busy": "2026-08-31T06:01:24.636982Z",
     "iopub.status.idle": "2026-08-31T06:01:24.638615Z",
     "shell.execute_reply": "2026-08-31T06:01:24.638424Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "output_type": "execute_result",
     "metadata": {},
     "data": {
      "text/plain": "np.int64(22)"
     },
     "execution_count": 10
    }
   ],
   "source": [
    "# np.percentile(scores, 85, method='nearest')  # nearest interpolation method is used to find the 85th percentile of the scores.\n",
    "np.percentile(scores, 85, method='nearest')  # nearest interpolation method is used to find the 85th percentile of the scores."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f935cc5f",
   "metadata": {},
   "source": [
    "The nearest-method 85th percentile is 22. Check its selected index directly, rather than assuming that another percentile convention must give the same rank.\n",
    "\n",
    "First, put the scores in increasing order:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "d1f65410",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-31T06:01:24.639593Z",
     "iopub.status.busy": "2026-08-31T06:01:24.639532Z",
     "iopub.status.idle": "2026-08-31T06:01:24.641482Z",
     "shell.execute_reply": "2026-08-31T06:01:24.641323Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "output_type": "execute_result",
     "metadata": {},
     "data": {
      "text/plain": "array([ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,\n        1,  4,  4,  4,  5,  6,  7,  7,  7,  7,  7,  8,  8,  8,  8,  8,  8,\n        8,  8,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 10,\n       10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n       10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n       11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n       12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,\n       13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14,\n       14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15,\n       15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16,\n       16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,\n       16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,\n       17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18,\n       18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,\n       19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20,\n       20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21,\n       21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,\n       21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22,\n       22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23,\n       23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n       24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,\n       25, 25])"
     },
     "execution_count": 11
    }
   ],
   "source": [
    "sorted_scores = np.sort(scores_and_sections.iloc[:, 1])\n",
    "sorted_scores"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "72180ed4",
   "metadata": {},
   "source": [
    "There are 359 scores. The nearest-method zero-based position is `(359 - 1) * 0.85`, or 304.3.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "64ca7fd7",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-31T06:01:24.642418Z",
     "iopub.status.busy": "2026-08-31T06:01:24.642361Z",
     "iopub.status.idle": "2026-08-31T06:01:24.643930Z",
     "shell.execute_reply": "2026-08-31T06:01:24.643730Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "output_type": "execute_result",
     "metadata": {},
     "data": {
      "text/plain": "304.3"
     },
     "execution_count": 12
    }
   ],
   "source": [
    "(len(sorted_scores) - 1) * 0.85\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "43fb2002",
   "metadata": {},
   "source": [
    "Round 304.3 to index 304, which is the 305th element of the sorted list. The next cell selects that value.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "ad08ccbc",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-31T06:01:24.644909Z",
     "iopub.status.busy": "2026-08-31T06:01:24.644832Z",
     "iopub.status.idle": "2026-08-31T06:01:24.646232Z",
     "shell.execute_reply": "2026-08-31T06:01:24.646075Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "output_type": "execute_result",
     "metadata": {},
     "data": {
      "text/plain": "np.int64(22)"
     },
     "execution_count": 13
    }
   ],
   "source": [
    "# The 305th sorted value is at zero-based index 304.\n",
    "sorted_scores[304]\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b49e9642",
   "metadata": {},
   "source": [
    "That's the same as the answer we got by using `percentile`. In future, we will just use `percentile`."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9a016031",
   "metadata": {},
   "source": [
    "## Quartiles\n",
    "\n",
    "The first and third quartiles are the 25th and 75th percentiles. State the convention used when reporting them. Here, calculate them with `nearest` and calculate the ordinary median separately.\n",
    "\n",
    "For these 359 scores, the ordinary median and nearest-method 50th percentile agree because the list has an odd length. That agreement is not guaranteed with an even sample size.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "aebbce66",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-31T06:01:24.647160Z",
     "iopub.status.busy": "2026-08-31T06:01:24.647108Z",
     "iopub.status.idle": "2026-08-31T06:01:24.648748Z",
     "shell.execute_reply": "2026-08-31T06:01:24.648581Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "25th percentile: 11\nMedian: 16.0\n75th percentile: 20\n"
    }
   ],
   "source": [
    "q_25 = np.percentile(scores, 25, method='nearest').item()\n",
    "median = np.median(scores).item()\n",
    "q_75 = np.percentile(scores, 75, method='nearest').item()\n",
    "print('25th percentile:', q_25)\n",
    "print('Median:', median)\n",
    "print('75th percentile:', q_75)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3372150e",
   "metadata": {},
   "source": [
    "The interval from the first to the third quartile describes the middle of the **individual scores**. It is not a confidence interval for a population mean or median. With ties and finite-sample percentile conventions, it need not contain exactly 50% of observations.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cell-dc7187d9",
   "metadata": {},
   "source": [
    "\n",
    "## Section Practice\n",
    "\n",
    "Use this short exercise to check the main workflow from this section.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "cell-7e048b6c",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-31T06:01:24.649765Z",
     "iopub.status.busy": "2026-08-31T06:01:24.649699Z",
     "iopub.status.idle": "2026-08-31T06:01:24.651058Z",
     "shell.execute_reply": "2026-08-31T06:01:24.650838Z"
    },
    "tags": [
     "thebe-interactive"
    ]
   },
   "outputs": [],
   "source": [
    "### Exercise: Practice Percentiles\n",
    "# A call center recorded 12 hold times in minutes.\n",
    "#   1. Compute the nearest-method 90th percentile.\n",
    "#   2. Check it by sorting the values and selecting the index nearest\n",
    "#      (n - 1) * 0.90. Use int(np.rint(...)) for NumPy's tie convention.\n",
    "#   3. Print both results.\n",
    "import numpy as np\n",
    "hold_times = np.array([3, 7, 2, 12, 5, 4, 9, 6, 15, 3, 8, 5])\n",
    "### Your code starts here.\n",
    "\n",
    "### Your code ends here.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "cell-0811affc",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-08-31T06:01:24.651917Z",
     "iopub.status.busy": "2026-08-31T06:01:24.651863Z",
     "iopub.status.idle": "2026-08-31T06:01:24.653293Z",
     "shell.execute_reply": "2026-08-31T06:01:24.653150Z"
    },
    "tags": [
     "hide-input"
    ]
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "np.percentile: 12\nDefinition: 12\n"
    }
   ],
   "source": [
    "### Solution\n",
    "import numpy as np\n",
    "hold_times = np.array([3, 7, 2, 12, 5, 4, 9, 6, 15, 3, 8, 5])\n",
    "by_numpy = np.percentile(hold_times, 90, method='nearest')\n",
    "sorted_times = np.sort(hold_times)\n",
    "index = int(np.rint((len(sorted_times) - 1) * 0.90))\n",
    "by_definition = sorted_times[index]\n",
    "print('np.percentile:', by_numpy)\n",
    "print('Definition:', by_definition)\n",
    "# Eleven of the 12 observed waits are at most 12 minutes. This sample\n",
    "# percentile does not guarantee that 90% of future waits meet the target.\n"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
