title: Python Pandas Create New DataFrame Using Existing DataFrame to Query Another DataFrame
body: <p>My goal is to build a new <code>DataFrame</code> named <code>df3</code> (dataframe 3).</p>
  
  <p>Using <code>df1</code>'s <code>['Header 1', 'Header 2', 'Normalized']</code> values, how do I look in <code>df2</code> rows to find where <code>df1</code> <code>['Header 1', 'Header 2', 'Normalized']</code> is equal to <code>df2</code> <code>['Header 1', 'Header 2', 'Normalized']</code> and build a new <code>DataFrame</code> from the result?</p>
  
  <p>For example, in row <code>0</code> of <code>df1</code>, the <code>Header 1</code>, <code>Header 2</code>, and <code>Normalized</code> equal <code>df2</code> rows <code>0</code>, <code>1</code>.</p>
  
  <p><code>df1</code></p>
  
  <pre><code>            Header 1 Header 2    Header 3 Normalized    Status Match type
  0             Boston  Label 1  "phrase 1"   phrase 1  eligible     Phrase
  1       DC/Baltimore  Label 2  [phrase 2]   phrase 2  eligible      Exact
  2          Philly/NJ  Label 3  "phrase 3"   phrase 3  eligible     Phrase
  3          Philly/NJ  Label 4  "phrase 4"   phrase 4  eligible     Phrase
  4          Philly/NJ  Label 5  "phrase 5"   phrase 5  eligible     Phrase
  5           Portland  Label 6  "phrase 6"   phrase 6  eligible     Phrase
  6  Raleigh/Charlotte  Label 7  [phrase 7]   phrase 7  eligible      Exact
  7  Raleigh/Charlotte  Label 8  "phrase 8"   phrase 8  eligible     Phrase
  </code></pre>
  
  <p><code>df2</code></p>
  
  <pre><code>             Header 1  Header 2     Header 3 Normalized    Status Match type
  0              Boston   Label 1   +phrase +1   phrase 1  eligible      Broad
  1              Boston   Label 1   [phrase 1]   phrase 1  eligible      Exact
  2        DC/Baltimore   Label 2   +phrase +2   phrase 2  eligible      Broad
  3        DC/Baltimore   Label 2   "phrase 2"   phrase 2  eligible     Phrase
  4                Frag  Label 22       [what]       what  eligible      Exact
  5           Philly/NJ   Label 3   +phrase +3   phrase 3  eligible      Broad
  6           Philly/NJ   Label 4   +phrase +4   phrase 4  eligible      Broad
  7           Philly/NJ   Label 5   +phrase +5   phrase 5  eligible      Broad
  8           Philly/NJ   Label 3   [phrase 3]   phrase 3  eligible      Exact
  9           Philly/NJ   Label 4   [phrase 4]   phrase 4  eligible      Exact
  10          Philly/NJ   Label 5   [phrase 5]   phrase 5  eligible      Exact
  11           Portland   Label 6   +phrase +6   phrase 6  eligible      Broad
  12           Portland   Label 6   [phrase 6]   phrase 6  eligible      Exact
  13  Raleigh/Charlotte   Label 7   +phrase +7   phrase 7  eligible      Broad
  14  Raleigh/Charlotte   Label 8   +phrase +8   phrase 8  eligible      Broad
  15  Raleigh/Charlotte   Label 7   "phrase 7"   phrase 7  eligible     Phrase
  16  Raleigh/Charlotte   Label 8   [phrase 8]   phrase 8  eligible      Exact
  </code></pre>
  
  <p><code>df3</code> final result from this example would include all rows from <code>df1</code> and every row from <code>df2</code> except row (<code>index</code>) <code>4</code> because its <code>['Header 1', 'Header 2', 'Normalized']</code> does not match any row in <code>df1</code>.</p>
  
  <p>The key thing I don't understand is how to use multiple criteria from one DataFrame to filter data in another DataFrame?</p>
  
  <p><strong>Edit 1:</strong>
  My end-goal is to have <code>df3</code> look like the below table.  The key thing to note is that it <code>merges</code> <code>df1</code> and <code>df2</code> <strong>entire rows</strong> where <code>['Header 1', 'Header 2', 'Normalized']</code> are equal.  I've tried the <code>merge</code> suggestions.  It looks exactly like what I need but I see column headers with suffixes <code>_x</code>, <code>_y</code> appended.  How do I output the below in one swoop?  Do I have to change header labels to match that of the original table and drop a few columns?  Or is there a better approach?</p>
  
  <pre><code>             Header 1   Header 2  Header 3   Normalized  Status   Match type
  0              Boston   Label 1   "phrase 1"   phrase 1  eligible     Phrase
  1        DC/Baltimore   Label 2   [phrase 2]   phrase 2  eligible     Exact
  2           Philly/NJ   Label 3   "phrase 3"   phrase 3  eligible     Phrase
  3           Philly/NJ   Label 4   "phrase 4"   phrase 4  eligible     Phrase
  4           Philly/NJ   Label 5   "phrase 5"   phrase 5  eligible     Phrase
  5            Portland   Label 6   "phrase 6"   phrase 6  eligible     Phrase
  6   Raleigh/Charlotte   Label 7   [phrase 7]   phrase 7  eligible     Exact
  7   Raleigh/Charlotte   Label 8   "phrase 8"   phrase 8  eligible     Phrase
  0              Boston   Label 1   +phrase +1   phrase 1  eligible     Broad
  1              Boston   Label 1   [phrase 1]   phrase 1  eligible     Exact
  2        DC/Baltimore   Label 2   +phrase +2   phrase 2  eligible     Broad
  3        DC/Baltimore   Label 2   "phrase 2"   phrase 2  eligible     Phrase
  5           Philly/NJ   Label 3   +phrase +3   phrase 3  eligible     Broad
  6           Philly/NJ   Label 4   +phrase +4   phrase 4  eligible     Broad
  7           Philly/NJ   Label 5   +phrase +5   phrase 5  eligible     Broad
  8           Philly/NJ   Label 3   [phrase 3]   phrase 3  eligible     Exact
  9           Philly/NJ   Label 4   [phrase 4]   phrase 4  eligible     Exact
  10          Philly/NJ   Label 5   [phrase 5]   phrase 5  eligible     Exact
  11           Portland   Label 6   +phrase +6   phrase 6  eligible     Broad
  12           Portland   Label 6   [phrase 6]   phrase 6  eligible     Exact
  13  Raleigh/Charlotte   Label 7   +phrase +7   phrase 7  eligible     Broad
  14  Raleigh/Charlotte   Label 8   +phrase +8   phrase 8  eligible     Broad
  15  Raleigh/Charlotte   Label 7   "phrase 7"   phrase 7  eligible     Phrase
  16  Raleigh/Charlotte   Label 8   [phrase 8]   phrase 8  eligible     Exact
  </code></pre>