{"id":"l-pda-2-1","courseId":"python-data-analysis","lang":"en","kind":"lesson","summary":"Build pandas Series and DataFrames from Python lists and dictionaries, run calculations on whole columns at once, and predict how pandas lines values up by their index labels.","html":"<p>In the last section’s exercise, month names lived in one list and revenues in another, and you had to find the best month by its position and then look up the name in the other list. Sort one list and forget the other, and every month gets the wrong revenue without any error. pandas exists to make that kind of mistake hard: values carry their labels with them.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">Series: a column with labels</h2>\n<p>A <strong>Series</strong> is a one-dimensional array of values plus an <strong>index</strong>: one label per value.</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"python\" data-run=\"python\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">Python</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"python\" data-index=\"0\" aria-label=\"Run this example\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>Run</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pandas </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">as</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">months </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Jan\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Feb\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Mar\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Apr\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"May\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Jun\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">          \"Jul\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Aug\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Sep\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Oct\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Nov\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Dec\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">revenue </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd.Series(</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    [</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">16167</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">14906</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">18208</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">18817</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">17428</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">13933</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">     22968</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">32042</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">25514</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">30339</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">75334</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">41153</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">],</span></span>\n<span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">    index</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">months,</span></span>\n<span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">    name</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"revenue_2025\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(revenue.head(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">3</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">))</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(revenue[</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Nov\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">], revenue.idxmax(), revenue.sum())</span></span></code></pre><div class=\"run-output\" data-run-output=\"0\" hidden></div></div>\n<p><code dir=\"ltr\">import pandas as pd</code> loads the library under its universal nickname; every pandas tutorial and Stack Overflow answer uses <code dir=\"ltr\">pd</code>. <code dir=\"ltr\">revenue[&quot;Nov&quot;]</code> looks a value up by label, and <code dir=\"ltr\">idxmax()</code> returns the <strong>label</strong> of the largest value, which is the whole parallel-lists dance from Section 1 in one call.</p>\n<p>The last line of the printed Series reads <code dir=\"ltr\">Name: revenue_2025, dtype: int64</code>. The <strong>dtype</strong> is the type of every value in the column: <code dir=\"ltr\">int64</code> for whole numbers, <code dir=\"ltr\">float64</code> for decimals, <code dir=\"ltr\">object</code> (or <code dir=\"ltr\">str</code> in pandas 3) for text, <code dir=\"ltr\">bool</code>, and <code dir=\"ltr\">datetime64</code> for dates. One column, one type; that rule is what makes pandas fast.</p>\n<h2 id=\"sec-2\" tabindex=\"-1\">Calculations on every value at once</h2>\n<p>Arithmetic and comparisons on a Series apply to each value and return a new Series with the same index. This is called <strong>vectorised</strong> code: you describe the operation on the whole column and pandas does the loop in fast compiled code.</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"python\" data-run=\"python\" data-index=\"1\"><div class=\"code-head\"><span class=\"code-title\">Python</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"python\" data-index=\"1\" aria-label=\"Run this example\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>Run</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pandas </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">as</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">revenue </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd.Series([</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">30339</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">75334</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">41153</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">], </span><span style=\"color:#953800;--shiki-dark:#FFA657\">index</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">[</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Oct\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Nov\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Dec\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">])</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(revenue </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">*</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 1.05</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)              </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># every month, 5% higher</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(revenue </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">/</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> revenue.sum())     </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># each month's share of Q4</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(revenue </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">></span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 40000</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)             </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># a Series of True/False</span></span></code></pre><div class=\"run-output\" data-run-output=\"1\" hidden></div></div>\n<p>The <code dir=\"ltr\">True</code>/<code dir=\"ltr\">False</code> Series on the last line looks like a curiosity now. In Lesson 2.4 it becomes the main way you filter rows.</p>\n<h2 id=\"sec-3\" tabindex=\"-1\">Alignment: pandas matches labels, not positions</h2>\n<p>When you combine two Series, pandas lines them up by index label before it calculates. Here is Q4 2025 against Q4 2024, with the months deliberately written in a different order and one month missing:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"python\" data-run=\"python\" data-index=\"2\"><div class=\"code-head\"><span class=\"code-title\">Python</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"python\" data-index=\"2\" aria-label=\"Run this example\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>Run</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pandas </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">as</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">q4_2025 </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd.Series([</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">30339</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">75334</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">41153</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">], </span><span style=\"color:#953800;--shiki-dark:#FFA657\">index</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">[</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Oct\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Nov\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Dec\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">])</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">q4_2024 </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd.Series([</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">29177</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">9360</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">], </span><span style=\"color:#953800;--shiki-dark:#FFA657\">index</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">[</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Nov\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Oct\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">])</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(q4_2025 </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">-</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> q4_2024)</span></span></code></pre><div class=\"run-output\" data-run-output=\"2\" hidden></div></div>\n<p>October is subtracted from October and November from November, regardless of order. December exists only in 2025, so its result is <code dir=\"ltr\">NaN</code> (“not a number”), pandas’ marker for a missing value. Notice the result became <code dir=\"ltr\">float64</code>: in classic NumPy-backed columns, <code dir=\"ltr\">NaN</code> is a float, so an integer column that gains a missing value turns into floats.</p>\n<figure class=\"diagram\"><svg class=\"diagram-svg\" focusable=\"false\" viewBox=\"0 0 700 230\" role=\"img\" aria-labelledby=\"l-pda-2-1-t1\"><defs><marker id=\"arrow-l-pda-2-1-1\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto-start-reverse\"><path d=\"M0 0 L10 5 L0 10 z\" class=\"d-arrowhead\"/></marker></defs>\n  <title id=\"l-pda-2-1-t1\">Left Series has Oct, Nov, Dec. Right Series has Nov and Oct in a different order. Arrows connect matching labels. The result has Oct and Nov computed, and Dec is NaN because it has no partner.</title>\n  <text class=\"d-label-strong\" x=\"70\" y=\"26\" text-anchor=\"middle\">q4_2025</text>\n  <rect class=\"d-box\" x=\"20\" y=\"40\" width=\"100\" height=\"40\" rx=\"6\"/>\n  <text class=\"d-label\" x=\"70\" y=\"65\" text-anchor=\"middle\">Oct 30339</text>\n  <rect class=\"d-box\" x=\"20\" y=\"90\" width=\"100\" height=\"40\" rx=\"6\"/>\n  <text class=\"d-label\" x=\"70\" y=\"115\" text-anchor=\"middle\">Nov 75334</text>\n  <rect class=\"d-box\" x=\"20\" y=\"140\" width=\"100\" height=\"40\" rx=\"6\"/>\n  <text class=\"d-label\" x=\"70\" y=\"165\" text-anchor=\"middle\">Dec 41153</text>\n  <text class=\"d-label-strong\" x=\"300\" y=\"26\" text-anchor=\"middle\">q4_2024</text>\n  <rect class=\"d-box\" x=\"250\" y=\"40\" width=\"100\" height=\"40\" rx=\"6\"/>\n  <text class=\"d-label\" x=\"300\" y=\"65\" text-anchor=\"middle\">Nov 29177</text>\n  <rect class=\"d-box\" x=\"250\" y=\"90\" width=\"100\" height=\"40\" rx=\"6\"/>\n  <text class=\"d-label\" x=\"300\" y=\"115\" text-anchor=\"middle\">Oct 9360</text>\n  <path class=\"d-line d-dashed\" d=\"M120 60 L250 110\"/>\n  <path class=\"d-line d-dashed\" d=\"M120 110 L250 60\"/>\n  <path class=\"d-arrow\" d=\"M370 110 L440 110\" marker-end=\"url(#arrow-l-pda-2-1-1)\"/>\n  <text class=\"d-label-strong\" x=\"560\" y=\"26\" text-anchor=\"middle\">difference</text>\n  <rect class=\"d-box-success\" x=\"490\" y=\"40\" width=\"140\" height=\"40\" rx=\"6\"/>\n  <text class=\"d-label\" x=\"560\" y=\"65\" text-anchor=\"middle\">Oct 20979</text>\n  <rect class=\"d-box-success\" x=\"490\" y=\"90\" width=\"140\" height=\"40\" rx=\"6\"/>\n  <text class=\"d-label\" x=\"560\" y=\"115\" text-anchor=\"middle\">Nov 46157</text>\n  <rect class=\"d-box-warn\" x=\"490\" y=\"140\" width=\"140\" height=\"40\" rx=\"6\"/>\n  <text class=\"d-label\" x=\"560\" y=\"165\" text-anchor=\"middle\">Dec NaN</text>\n  <text class=\"d-label-muted\" x=\"350\" y=\"215\" text-anchor=\"middle\">labels are matched first; a label with no partner gives NaN</text>\n</svg><figcaption>Two Series combine by matching index labels</figcaption></figure>\n<aside class=\"callout callout-mistake\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\"/><path d=\"M12 9v4\"/><path d=\"M12 17h.01\"/></svg><span><span class=\"callout-kind\">Common mistake</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>Expecting positional matching</span></p>\n<p>If two Series have different indexes, say one labelled by month name and one by month number, every result is <code dir=\"ltr\">NaN</code> and nothing errors. When a calculation suddenly returns a column of <code dir=\"ltr\">NaN</code>, compare the two indexes with <code dir=\"ltr\">print(a.index, b.index)</code> before anything else.</p>\n</aside>\n<h2 id=\"sec-4\" tabindex=\"-1\">DataFrame: a table of Series</h2>\n<p>A <strong>DataFrame</strong> is several Series side by side, sharing one index. The easiest way to build a small one is the dictionary-of-lists shape you met in Lesson 1.3, one key per column:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"python\" data-run=\"python\" data-index=\"3\"><div class=\"code-head\"><span class=\"code-title\">Python</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"python\" data-index=\"3\" aria-label=\"Run this example\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>Run</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pandas </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">as</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">products </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd.DataFrame({</span></span>\n<span class=\"line\"><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"name\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: [</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Cast Iron Skillet 26cm\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Burr Coffee Grinder\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Standing Desk 140cm\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Cork Yoga Mat\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">],</span></span>\n<span class=\"line\"><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"unit_price\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: [</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">39</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">129</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">449</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">72</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">],</span></span>\n<span class=\"line\"><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"unit_cost\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: [</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">17.45</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">76.99</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">204.98</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">41.52</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">],</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">})</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(products)</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(products.shape)       </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># (rows, columns)</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(products.dtypes)</span></span></code></pre><div class=\"run-output\" data-run-output=\"3\" hidden></div></div>\n<p>Three attributes describe any DataFrame, and you will print them constantly. <code dir=\"ltr\">shape</code> is the (rows, columns) pair, <code dir=\"ltr\">columns</code> lists the column names, and <code dir=\"ltr\">index</code> holds the row labels. None of them has parentheses, because they are stored facts about the table rather than actions; <code dir=\"ltr\">head()</code> and <code dir=\"ltr\">sum()</code> do work, so they are called with parentheses. Mixing the two up gives either a method printed as <code dir=\"ltr\">&lt;bound method ...&gt;</code> or a <code dir=\"ltr\">TypeError: 'tuple' object is not callable</code>, both of which you can now recognise.</p>\n<p>pandas gave the rows a default index, 0 to 3. Each column is a Series you can pull out with square brackets, and column arithmetic lines up row by row because the columns share that index:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"python\" data-run=\"python\" data-index=\"4\"><div class=\"code-head\"><span class=\"code-title\">Python</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"python\" data-index=\"4\" aria-label=\"Run this example\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>Run</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pandas </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">as</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">products </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd.DataFrame({</span></span>\n<span class=\"line\"><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"name\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: [</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Cast Iron Skillet 26cm\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Burr Coffee Grinder\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Standing Desk 140cm\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Cork Yoga Mat\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">],</span></span>\n<span class=\"line\"><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"unit_price\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: [</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">39</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">129</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">449</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">72</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">],</span></span>\n<span class=\"line\"><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"unit_cost\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: [</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">17.45</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">76.99</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">204.98</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">41.52</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">],</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">})</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">margin </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> products[</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"unit_price\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">] </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">-</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> products[</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"unit_cost\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(margin)</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">type</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(products[</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"unit_price\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]))</span></span></code></pre><div class=\"run-output\" data-run-output=\"4\" hidden></div></div>\n<p>The skillet earns 21.55 dollars per unit and the standing desk 244.02. Four rows or four million, the code is the same, and that is the real promise of pandas: you think in columns, not in cells.</p>\n<aside class=\"callout callout-tip\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5\"/><path d=\"M9 18h6\"/><path d=\"M10 22h4\"/></svg><span><span class=\"callout-kind\">Tip</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>print(df) versus df</span></p>\n<p>In a Jupyter notebook, writing <code dir=\"ltr\">products</code> alone on the last line of a cell displays a formatted table. In scripts and in this course’s Run blocks, nothing is shown unless you call <code dir=\"ltr\">print()</code>. Both are the same object; only the display differs.</p>\n</aside>\n<p>Building tables by hand is for learning. Next you load Cartwheel’s real CSV files and learn the inspection routine to run before you trust any of them.</p>\n","toc":[{"id":"sec-1","text":"Series: a column with labels","level":2},{"id":"sec-2","text":"Calculations on every value at once","level":2},{"id":"sec-3","text":"Alignment: pandas matches labels, not positions","level":2},{"id":"sec-4","text":"DataFrame: a table of Series","level":2}],"takeaways":["A Series is a column of values with an index of labels; a DataFrame is a table of Series that share one index.","Arithmetic on a Series applies to every value at once, so you write <code dir=\"ltr\">prices * 1.05</code> instead of a loop.","Operations between two Series line up by index label, not by position; labels present in only one side produce <code dir=\"ltr\">NaN</code>.","<code dir=\"ltr\">df[&quot;col&quot;]</code> gives one column as a Series, and <code dir=\"ltr\">df.shape</code>, <code dir=\"ltr\">df.columns</code>, <code dir=\"ltr\">df.index</code> and <code dir=\"ltr\">df.dtypes</code> describe the table."],"further":[{"title":"Intro to data structures (Series and DataFrame)","url":"https://pandas.pydata.org/docs/user_guide/dsintro.html"},{"title":"pandas.DataFrame reference","url":"https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.html"}],"quiz":[{"q":"<p>What is <code dir=\"ltr\">growth[&quot;Oct&quot;]</code>?</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"python\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">Python</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">y2024 </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd.Series([</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">9360</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">29177</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">], </span><span style=\"color:#953800;--shiki-dark:#FFA657\">index</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">[</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Oct\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Nov\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">])</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">y2025 </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd.Series([</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">75334</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">30339</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">], </span><span style=\"color:#953800;--shiki-dark:#FFA657\">index</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">[</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Nov\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Oct\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">])</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">growth </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> y2025 </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">-</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> y2024</span></span></code></pre></div>\n","options":[{"text":"<code dir=\"ltr\">65,974</code>, the first value minus the first value","why":"That is position-based thinking. pandas matches values by their labels, not their order."},{"text":"<code dir=\"ltr\">20,979</code>, October 2025 minus October 2024","why":"Correct. pandas aligns both Series on the index, so each month is subtracted from the same month, whatever order they were written in."},{"text":"<code dir=\"ltr\">NaN</code>, because the indexes are in a different order","why":"Order does not matter for alignment; only labels that appear on one side alone produce <code dir=\"ltr\">NaN</code>."}],"answer":1},{"q":"<p><code dir=\"ltr\">products</code> is a DataFrame with 48 rows and 7 columns. What does <code dir=\"ltr\">products.shape</code> return?</p>","options":[{"text":"<code dir=\"ltr\">(7, 48)</code>","why":"Shape is always rows first, then columns."},{"text":"<code dir=\"ltr\">336</code>","why":"That is <code dir=\"ltr\">products.size</code>, the total number of cells."},{"text":"<code dir=\"ltr\">(48, 7)</code>","why":"Correct. <code dir=\"ltr\">shape</code> is a tuple of (rows, columns), and it is the fastest sanity check after loading data."},{"text":"<code dir=\"ltr\">48</code>","why":"That is <code dir=\"ltr\">len(products)</code>, which counts rows only."}],"answer":2},{"q":"<p>Which line raises every product’s price by 5% without a loop?</p>","options":[{"text":"<code dir=\"ltr\">products[&quot;unit_price&quot;] * 1.05</code>","why":"Correct. Arithmetic on a Series applies to every value and returns a new Series of the same length."},{"text":"<code dir=\"ltr\">[p * 1.05 for p in products]</code>","why":"Looping over a DataFrame gives you its column names, not its rows, so this tries to multiply strings."},{"text":"<code dir=\"ltr\">products * 1.05</code>","why":"This multiplies every column, including names and ids, and fails on the text columns."}],"answer":0},{"q":"<p>In the last exercise of Section 1 you kept month names and revenues in two parallel lists. What problem does a Series fix?</p>","options":[{"text":"Lists cannot hold more than 12 values.","why":"Lists can hold millions of values; size was never the issue."},{"text":"Lists cannot store floats with decimals.","why":"Lists hold any type, floats included."},{"text":"The labels travel with the values, so sorting or filtering can never mix up which revenue belongs to which month.","why":"Correct. With two lists, sorting one and not the other silently breaks the pairing. A Series keeps label and value together."}],"answer":2}],"exercise":{"kind":"python","files":[],"starter":"import pandas as pd\n\nmonths = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\",\n          \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"]\nvalues = [16167, 14906, 18208, 18817, 17428, 13933,\n          22968, 32042, 25514, 30339, 75334, 41153]\n\n# 1. A Series of the values, labelled by month\nrevenue = None\n\n# 2. Label of the best month\nbest_month = None\n\n# 3. Each month's share of the year (a Series that sums to 1)\nshare = None\n\n# 4. A DataFrame with columns name, unit_price, unit_cost for these products\n#    Cast Iron Skillet 26cm  39  17.45\n#    Burr Coffee Grinder    129  76.99\n#    2-Person Dome Tent     149  83.09\nproducts = None\n\n# 5. A Series: unit_price minus unit_cost for each product\nmargin = None\n","solution":"import pandas as pd\n\nmonths = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\",\n          \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"]\nvalues = [16167, 14906, 18208, 18817, 17428, 13933,\n          22968, 32042, 25514, 30339, 75334, 41153]\n\nrevenue = pd.Series(values, index=months)\nbest_month = revenue.idxmax()\nshare = revenue / revenue.sum()\n\nproducts = pd.DataFrame({\n    \"name\": [\"Cast Iron Skillet 26cm\", \"Burr Coffee Grinder\", \"2-Person Dome Tent\"],\n    \"unit_price\": [39, 129, 149],\n    \"unit_cost\": [17.45, 76.99, 83.09],\n})\nmargin = products[\"unit_price\"] - products[\"unit_cost\"]\n","checks":[{"id":"series","test":"isinstance(revenue, pd.Series) and list(revenue.index) == months and int(revenue['Nov']) == 75334"},{"id":"best-month","test":"best_month == 'Nov'"},{"id":"share","test":"isinstance(share, pd.Series) and round(float(share.sum()), 6) == 1.0 and round(float(share['Nov']), 4) == 0.2305"},{"id":"products","test":"isinstance(products, pd.DataFrame) and products.shape == (3, 3) and set(products.columns) == {'name', 'unit_price', 'unit_cost'}"},{"id":"margin","test":"isinstance(margin, pd.Series) and [round(float(x), 2) for x in margin] == [21.55, 52.01, 65.91]"}],"title":"Your first Series and DataFrame","prompt":"<p>Build <code dir=\"ltr\">revenue</code>, a Series of <code dir=\"ltr\">values</code> labelled by <code dir=\"ltr\">months</code>. Set <code dir=\"ltr\">best_month</code> to the label of its largest value and <code dir=\"ltr\">share</code> to each month’s share of the yearly total (a Series that sums to 1). Then build <code dir=\"ltr\">products</code>, a DataFrame with the columns <code dir=\"ltr\">name</code>, <code dir=\"ltr\">unit_price</code> and <code dir=\"ltr\">unit_cost</code> holding the three products listed in the comments, in that order, and <code dir=\"ltr\">margin</code>, a Series of <code dir=\"ltr\">unit_price</code> minus <code dir=\"ltr\">unit_cost</code>.</p>\n","hints":["<code dir=\"ltr\">pd.Series(values, index=months)</code> attaches the labels.","<code dir=\"ltr\">revenue.idxmax()</code> returns a label; dividing a Series by a single number divides every value.","Build the DataFrame from a dictionary of lists, one key per column, then subtract one column from the other: <code dir=\"ltr\">products[&quot;unit_price&quot;] - products[&quot;unit_cost&quot;]</code>."],"explanation":"<p>Passing <code dir=\"ltr\">index=months</code> makes each revenue carry its month, so <code dir=\"ltr\">idxmax()</code> answers “which month?” directly. <code dir=\"ltr\">revenue / revenue.sum()</code> divides every value by one total: a single number combines with every element of a Series (this is called broadcasting). For the DataFrame, the dictionary keys become column names and each list becomes a column. Subtracting two columns lines them up by the shared row index, giving the skillet a margin of 21.55, the grinder 52.01 and the tent 65.91.</p>\n","checkLabels":{"series":"<code dir=\"ltr\">revenue</code> is a Series labelled Jan to Dec","best-month":"<code dir=\"ltr\">best_month</code> is <code dir=\"ltr\">&quot;Nov&quot;</code>","share":"<code dir=\"ltr\">share</code> sums to 1, with November at about 23%","products":"<code dir=\"ltr\">products</code> is a 3 × 3 DataFrame with the right columns","margin":"<code dir=\"ltr\">margin</code> holds 21.55, 52.01 and 65.91"}},"words":694,"readMinutes":3}