<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: PJ Trainor</title>
    <description>The latest articles on DEV Community by PJ Trainor (@pj_trainor).</description>
    <link>https://dev.to/pj_trainor</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F58585%2Fd1edc92a-e9d3-46bc-ac01-29e6394f25ae.jpg</url>
      <title>DEV Community: PJ Trainor</title>
      <link>https://dev.to/pj_trainor</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pj_trainor"/>
    <language>en</language>
    <item>
      <title>Better Plots (in Three Lines!)</title>
      <dc:creator>PJ Trainor</dc:creator>
      <pubDate>Thu, 14 Mar 2019 00:39:50 +0000</pubDate>
      <link>https://dev.to/pj_trainor/better-plots-in-three-lines-2eb7</link>
      <guid>https://dev.to/pj_trainor/better-plots-in-three-lines-2eb7</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fnnbgeeir3pgi6i7rsbhv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fnnbgeeir3pgi6i7rsbhv.png" alt="A prettier plot, with just a little more code!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you've done any plotting in python, you've almost certainly used matplotlib. While it offers a simple approach to making plots, they are sometimes... well they can be a bit ugly, by default.&lt;/p&gt;

&lt;p&gt;I'll go over two quick tips to give your plots a little more personality:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Replacing the default styles&lt;/li&gt;
&lt;li&gt;Making prettier titles&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; There are plenty of other plotting options with their own styles (seaborn, plotly, bokeh, etc.), but matplotlib is the most widely used, so that's what I'll focus on&lt;/p&gt;

&lt;p&gt;You can skip to the repl.it below to play around with these styles!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  1. Replacing the Default Styles
&lt;/h1&gt;

&lt;p&gt;Next time you type in that import statement, consider adding &lt;em&gt;just one&lt;/em&gt; more line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;matplotlib.pyplot&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ggplot&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now when you make a plot, it will use the styles found in &lt;a href="https://ggplot2.tidyverse.org/" rel="noopener noreferrer"&gt;ggplot&lt;/a&gt;, a popular plotting library in R.&lt;/p&gt;

&lt;p&gt;There are &lt;a href="https://matplotlib.org/gallery/style_sheets/style_sheets_reference.html" rel="noopener noreferrer"&gt;plenty of other options&lt;/a&gt;, such as fivethirtyeight and seaborn-colorblind!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: If you don't want to apply one style to every plot, you can do:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ggplot&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h1&gt;
  
  
  2. Making Prettier Titles
&lt;/h1&gt;

&lt;p&gt;Matplotlib puts titles in the center, right at the top. Did you know you can move that title around? Did you know that you can have multiple titles? We can use &lt;em&gt;both&lt;/em&gt; to make nicer titles:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The Main Title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;loc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;left&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fontsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a subtitle&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;loc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;right&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fontsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;grey&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If you have something plotted already, then this moves your main title to the left, and adds a smaller and greyed-out subtitle on the right. It's a great way to give your plots more context, and make them look better!&lt;/p&gt;

&lt;p&gt;I'll even leave you with a function that makes this easier to implement:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fancy_titles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;loc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;left&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fontsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;ax&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;loc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;right&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fontsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;grey&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;loc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;left&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fontsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;loc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;right&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fontsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;grey&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;fancy_titles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;A Cool Title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a cooler subtitle&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Lastly, here's a repl.it, so you can play around with different styles:&lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@PjTrainor/matplotlib-styles?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;



</description>
      <category>python</category>
      <category>dataviz</category>
      <category>matplotlib</category>
      <category>quicktip</category>
    </item>
    <item>
      <title>Extending the Pandas DataFrame</title>
      <dc:creator>PJ Trainor</dc:creator>
      <pubDate>Tue, 05 Mar 2019 12:49:46 +0000</pubDate>
      <link>https://dev.to/pj_trainor/extending-the-pandas-dataframe-133l</link>
      <guid>https://dev.to/pj_trainor/extending-the-pandas-dataframe-133l</guid>
      <description>&lt;p&gt;Pandas offers a lot of convenient utilities for handling tabular data. The pandas &lt;code&gt;DataFrame&lt;/code&gt; is versatile, but some operations can only be done in a single command. I'll offer some advice on how you can extend &lt;code&gt;DataFrame&lt;/code&gt; to better suit your workflow. Also, when I say &lt;code&gt;DataFrame&lt;/code&gt;, I'm referring to the &lt;a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html"&gt;class in the pandas library&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Suppose you had a collection of &lt;code&gt;students&lt;/code&gt;, and you'd like to select all the students that have an "A" in Ms. Frizzle's class.&lt;/p&gt;

&lt;p&gt;Here's one way to do this in pandas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;students&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"grade == 'A'"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"teacher == 'Frizzle'"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;But what if we had a custom method?&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;students&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;select_by_grade_and_teacher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Frizzle"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: by enclosing the operations in parentheses, you can chain several pandas operations on multiple lines, since they all return &lt;code&gt;DataFrame&lt;/code&gt;s. This is called method-chaining.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  What Extending Means
&lt;/h2&gt;

&lt;p&gt;All I want to do is add custom methods to the standard pandas &lt;code&gt;DataFrame&lt;/code&gt;. Custom methods are useful because they:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;♻️ simplify repeatable, multi-line logic&lt;/li&gt;
&lt;li&gt;⛓ chain with built-in methods in &lt;code&gt;DataFrame&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So &lt;strong&gt;extending just means adding additional methods to &lt;code&gt;DataFrame&lt;/code&gt;&lt;/strong&gt;; these methods can return another &lt;code&gt;DataFrame&lt;/code&gt;, or anything else.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: We could write a function, but that doesn't fit into the method-chaining workflow, producing more lines of code&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  How to Extend &lt;code&gt;DataFrame&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Since we'd like to add new methods to &lt;code&gt;DataFrame&lt;/code&gt; without losing the old ones, we should consider subclassing &lt;code&gt;DataFrame&lt;/code&gt;. That is, defining a new class that inherits from the &lt;code&gt;DataFrame&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;This comes with a few caveats. We need to make sure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🏠 it keeps all of the methods in &lt;code&gt;DataFrame&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;🤝 when a custom method is called, it returns our class, and not &lt;code&gt;DataFrame&lt;/code&gt; (i.e. not the subclass)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The second point ensures we can continue to use custom methods for method-chaining. &lt;/p&gt;

&lt;p&gt;The following class does just that:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ExtendedDataFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# use the __init__ method from DataFrame to ensure
&lt;/span&gt;        &lt;span class="c1"&gt;# that we're inheriting the correct behavior
&lt;/span&gt;        &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ExtendedDataFrame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# this method is makes it so our methods return an instance
&lt;/span&gt;    &lt;span class="c1"&gt;# of ExtendedDataFrame, instead of a regular DataFrame
&lt;/span&gt;    &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;property&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ExtendedDataFrame&lt;/span&gt;

    &lt;span class="c1"&gt;# now define a custom method!
&lt;/span&gt;    &lt;span class="c1"&gt;# note that `self` is a DataFrame
&lt;/span&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;select_by_grade_and_teacher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;grade&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;teacher&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"grade == @grade"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"teacher == @teacher"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;See it in action in this &lt;a href="https://repl.it/@PjTrainor/extending-pandas-dataframe"&gt;repl.it&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@PjTrainor/extending-pandas-dataframe?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The pandas documentation has a page &lt;a href="https://pandas.pydata.org/pandas-docs/stable/development/extending.html"&gt;on extensions&lt;/a&gt;, but it's quite advanced, and includes many other topics&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  When to Extend
&lt;/h2&gt;

&lt;p&gt;This is a useful pattern for data exploration, especially in Jupyter Notebooks, or any environment that has code-completion. You can use it to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⏲ shorten highly-repeated tasks&lt;/li&gt;
&lt;li&gt;👩🏽‍🎓 as a utility packaged with a specific dataset, to share with your team... especially if they're not pandas experts like you&lt;/li&gt;
&lt;li&gt;📊 construct methods that make plots outside of the &lt;a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.html"&gt;standard functionality&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;I do not recommend using this pattern in production&lt;/strong&gt;, since it's not officially endorsed by pandas. Furthermore, you run the risk of conflicting with the current/future &lt;code&gt;DataFrame&lt;/code&gt; API.&lt;/p&gt;

&lt;p&gt;I'll leave you with an extended &lt;code&gt;DataFrame&lt;/code&gt; that I often use. It has some more advanced features, and all of the methods begin with my initials, &lt;code&gt;pj_&lt;/code&gt; (so it's easier to find in code-completion).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/trainorpj/488a1c8809fc66a197835deaa62cfa86"&gt;Link to my DataFrame&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feel free to ask any questions, and let me know if you find something interesting!&lt;/p&gt;

</description>
      <category>python</category>
      <category>pandas</category>
      <category>tutorial</category>
      <category>datascience</category>
    </item>
  </channel>
</rss>
