Testing if a pandas DataFrame exists
<p>In my code, I have several variables which can either contain a pandas DataFrame or nothing at all.  Let's say I want to test and see if a certain DataFrame has been created yet or not.  My first thought would be to test for it like this:</p>

<pre><code>if df1:
    # do something
</code></pre>

<p>However, that code fails in this way:</p>

<pre><code>ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
</code></pre>

<p>Fair enough.  Ideally, I would like to have a presence test that works for either a DataFrame or Python None.  </p>

<p>Here is one way this can work:</p>

<pre><code>if not isinstance(df1, type(None)):
    # do something
</code></pre>

<p>However, testing for type is really slow.</p>

<pre><code>t = timeit.Timer('if None: pass')
t.timeit()
# approximately 0.04
t = timeit.Timer('if isinstance(x, type(None)): pass', setup='x=None')
t.timeit()
# approximately 0.4
</code></pre>

<p>Ouch.  Along with being slow, testing for NoneType isn't very flexible, either.  </p>

<p>A different solution would be to initialize <code>df1</code> as an empty DataFrame, so that the type would be the same in both the null and non-null cases.  I could then just test using <code>len()</code>, or <code>any()</code>, or something like that.  Making an empty DataFrame seems kind of silly and wasteful, though.</p>

<p>Another solution would be to have an indicator variable: <code>df1_exists</code>, which is set to False until <code>df1</code> is created.  Then, instead of testing <code>df1</code>, I would be testing <code>df1_exists</code>.  But this doesn't seem all that elegant, either.</p>

<p>Is there a better, more Pythonic way of handling this issue?  Am I missing something, or is this just an awkward side effect all the awesome things about pandas? </p>

<blockquote>
  <p>In my code, I have several variables which can either contain a pandas DataFrame or nothing at all</p>
</blockquote>

<p>They Pythonic way of indicating "nothing" is via <code>None</code>, and for checking "not nothing" via</p>

<pre><code>if df1 is not None:
    ...
</code></pre>

<p>I am not sure how critical time is here, but since you measured things:</p>

<pre><code>In [82]: t = timeit.Timer('if x is not None: pass', setup='x=None')

In [83]: t.timeit()
Out[83]: 0.022536039352416992

In [84]: t = timeit.Timer('if isinstance(x, type(None)): pass', setup='x=None')

In [85]: t.timeit()
Out[85]: 0.11571192741394043
</code></pre>

<p>So checking that something <code>is not None</code>, is also faster than the <code>isinstance</code> alternative.</p>

python pandas