Как избежать конфликтов имен в методе запроса pandas? - PullRequest
1 голос
/ 06 августа 2020

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

Python 3.8.5 (default, Aug  5 2020, 09:44:06) [MSC v.1916 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 7.15.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import pandas as pd
In [2]: pd.__version__
Out[2]: '1.0.5'
In [3]: df = pd.DataFrame({'A': [1, 2], 'B': [3, 4]}, 
               index=pd.DatetimeIndex(pd.date_range('20200101', '20200102'), name='datetime'))

In [4]: end = pd.to_datetime('20200101')
In [5]: df.query('datetime <= @end')

Однако приведенный выше код приводит к исключению:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-5-0656de8e993d> in <module>
----> 1 df.query('datetime <= @end')

e:\anaconda\lib\site-packages\pandas\core\frame.py in query(self, expr, inplace, **kwargs)
   3229         kwargs["level"] = kwargs.pop("level", 0) + 1
   3230         kwargs["target"] = None
-> 3231         res = self.eval(expr, **kwargs)
   3232
   3233         try:

...

e:\anaconda\lib\site-packages\pandas\core\computation\ops.py in evaluate(self, env, engine, parser, term_type, eval_in_python)
    434             # base cases
    435             if self.op in eval_in_python:
--> 436                 res = self.func(left.value, right.value)
    437             else:
    438                 from pandas.core.computation.eval import eval

TypeError: '<=' not supported between instances of 'type' and 'Timestamp'

Кажется, что pandas - это перепутал index datetime со встроенным типом datetime.datetime , как решить эту проблему (с запросом и сохранением имени индекса)?

EDIT

Я провёл больше тестов и получил интересный результат:

In [1]: import pandas as pd

In [2]: index = pd.MultiIndex.from_product([['T0', 'T1'], ['A', 'B']], names=['datetime', 'count'])

In [3]: frame = pd.DataFrame({'isnull': range(len(index))}, index=index)

In [4]: frame
Out[4]: 
                isnull
datetime count        
T0       A           0
         B           1
T1       A           2
         B           3

In [5]: frame.query('count == "A"')
Out[5]: 
                isnull
datetime count        
T0       A           0
T1       A           2

In [6]: frame.query('isnull < 2')
Out[6]: 
                isnull
datetime count        
T0       A           0
         B           1

In [7]: frame.query('datetime == "T0"')
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
D:\home\tools\Anaconda\lib\site-packages\pandas\core\indexes\base.py in get_loc(self, key, method, tolerance)
   2645             try:
-> 2646                 return self._engine.get_loc(key)
   2647             except KeyError:
...
pandas\_libs\hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item()

KeyError: False
  • имена вроде count и isnull работают в query;
  • , если dtype из datetime в индексе изменено на str, запрос вызывает KeyError, а не TypeError.

1 Ответ

2 голосов
/ 06 августа 2020

Это из-за имени индекса, который в данном случае совпадает с типом pandas, как вы можете видеть в ошибке. Как сказал Манакин в комментариях, вы можете использовать index вместо datetime для выполнения запроса:

df.query('index <= @end')

Или также измените имя индекса, чтобы избежать двусмысленности:

df.index.name='dates'
df.query('dates <= @end')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...