title: Converting a pandas crosstab into a stacked dataframe (a regular table)
body: <p>Given a pandas crosstab, how do you convert that into a stacked dataframe?</p>
  
  <p>Assume you have a stacked dataframe. First we convert it into a crosstab. Now I would like to revert back to the original stacked dataframe. I searched a problem statement that addresses this requirement, but could not find any that hits bang on. In case I have missed any, please leave a note to it in the comment section.  </p>
  
  <p>I would like to document the best practice here. So, thank you for your support.</p>
  
  <p>I know that <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.stack.html" rel="nofollow noreferrer">pandas.DataFrame.stack()</a> would be the best approach. But one needs to be careful of the the "level" stacking is applied to. </p>
  
  <p><strong>Input: Crosstab</strong>:  </p>
  
  <pre><code>
      Label   a   b   c   d   r
      ID                  
      1       0   1   0   0   0
      2       1   1   0   1   1
      3       1   0   0   0   1
      4       1   0   0   1   0
      6       1   0   0   0   0
      7       0   0   1   0   0
      8       1   0   1   0   0
      9       0   1   0   0   0
  
  </code></pre>
  
  <p><strong>Output: Stacked DataFrame</strong>:   </p>
  
  <pre><code>
          ID  Label
      0   1   b
      1   2   a
      2   2   b
      3   2   d
      4   2   r
      5   3   a
      6   3   r
      7   4   a
      8   4   d
      9   6   a
      10  7   c
      11  8   a
      12  8   c
      13  9   b
  
  </code></pre>
  
  <h2>Step-by-step Explanation:</h2>
  
  <p>First, let's make a function that would create our data. Note that it randomly generates the stacked dataframe, and so, the final output may differ from what I have given below.</p>
  
  <p><strong>Helper Function: Make the Stacked And Crosstab DataFrames</strong>  </p>
  
  <pre class="lang-py prettyprint-override"><code>import numpy as np
  import pandas as pd
  
  # Make stacked dataframe
  def _create_df():
      """
      This dataframe will be used to create a crosstab
      """
      B = np.array(list('abracadabra'))
      A = np.arange(len(B))
      AB = list()
      for i in range(20):
          a = np.random.randint(1,10)
          b = np.random.randint(1,10)
          AB += [(a,b)]
      AB = np.unique(np.array(AB), axis=0)
      AB = np.unique(np.array(list(zip(A[AB[:,0]], B[AB[:,1]]))), axis=0)
      AB_df = pd.DataFrame({'ID': AB[:,0], 'Label': AB[:,1]})
      return AB_df
  
  original_stacked_df = _create_df()
  
  # Make crosstab
  crosstab_df = pd.crosstab(original_stacked_df['ID'], 
                            original_stacked_df['Label']).reindex()
  </code></pre>
  
  <h2>What to expect?</h2>
  
  <p>You would expect a function to regenerate the stacked dataframe from the crosstab. I would provide my own solution to this in the answer section. If you could suggest something better that would be great.</p>
  
  <h1>Other References:</h1>
  
  <ul>
  <li>Closest stackoverflow discussion: <a href="https://stackoverflow.com/questions/55159119/pandas-stacking-a-dataframe">pandas stacking a dataframe
  </a></li>
  <li>Misleading stackoverflow question-topic: <a href="https://stackoverflow.com/questions/44257249/change-pandas-crossstab-dataframe-into-plain-table-format/57565200#57565200">change pandas crossstab dataframe into plain table format:
  </a></li>
  </ul>