Тестирование, если существует pandas DataFrame

В моем коде у меня есть несколько переменных, которые могут содержать Pandas DataFrame или вообще ничего. Скажем, я хочу протестировать и посмотреть, создан ли какой-то определенный DataFrame или нет. Моя первая мысль заключалась в том, чтобы проверить это следующим образом:

if df1:
    # do something

Однако этот код не работает таким образом:

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

Справедливо. В идеале, я хотел бы иметь тест присутствия, который работает либо для DataFrame, либо для Python None.

Вот один из способов:

if not isinstance(df1, type(None)):
    # do something

Тем не менее, тестирование для типа происходит очень медленно.

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

Уч. Наряду с медленностью, тестирование для NoneType также не очень гибкое.

Другим решением было бы инициализировать df1 как пустой DataFrame, так что тип был бы одинаковым как в случае с нулевым, так и непустым случаем. Я мог бы просто проверить с помощью len() или any(), или что-то в этом роде. Однако создание пустой DataFrame кажется глупым и расточительным.

Другим решением было бы иметь переменную индикатора: df1_exists, для которой установлено значение False до df1. Затем вместо тестирования df1 я бы тестировал df1_exists. Но это тоже не так элегантно.

Есть ли лучший, более питонический способ решения этой проблемы? Я что-то упускаю, или это просто неудобный побочный эффект от всех удивительных вещей о пандах?

Ответ 1

Вариант 1 (мой предпочтительный вариант)

Это @Ami Tavory's

Пожалуйста, выберите его ответ, если вам нравится этот подход

Это очень идиоматический питон для инициализации переменной с помощью None затем проверьте None чтобы что-то сделать с этой переменной.

df1 = None

if df1 is not None:
    print df1.head()

Вариант 2

Однако настройка пустой фреймворка вовсе не плохая идея.

df1 = pd.DataFrame()

if not df1.empty:
    print df1.head()

Вариант 3

Просто попробуйте.

try:
    print df1.head()
# catch when df1 is None
except AttributeError:
    pass
# catch when it hasn't even been defined
except NameError:
    pass

тайминг

Когда df1 находится в инициализированном состоянии или вообще не существует

enter image description here

Когда df1 - это кадр данных с чем-то в нем

df1 = pd.DataFrame(np.arange(25).reshape(5, 5), list('ABCDE'), list('abcde'))
df1

enter image description here

enter image description here

Ответ 2

В моем коде у меня есть несколько переменных, которые могут содержать панды DataFrame или вообще ничего

Они Pythonic способ указать "ничего" через None, а для проверки "ничего" через

if df1 is not None:
    ...

Я не уверен, как критическое время здесь, но поскольку вы измеряли вещи:

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

Поэтому проверка того, что что-то is not None, также быстрее, чем альтернатива isinstance.