Не удалось отфильтровать строки, содержащие определенное значение в столбце индекса после сброса индекса - PullRequest
0 голосов
/ 13 сентября 2018

Я организую данные ряда планов, которые содержат информацию о фазе плана, P (предварительный) или F (конечный). Я использую методы, показанные в примерах в документации для панд.

df1 = pd.read_excel('FilePath', sheetname = 'ForFilter')
df1


landuse_SUB_ID  TYPE    RECD_DATE   PHASE   LAND_USE    CPACTIONDA
0   24  1   2000-04-07  P   ROW 2000-05-04
1   24  1   2000-04-07  P   NONE    2000-05-04
2   25  1   2000-08-10  P   COMM    2000-09-08
3   34  1   2000-04-14  F   REC 2000-04-14
4   34  1   2000-04-14  F   SFD 2000-04-14
5   35  1   2000-01-20  P   NONE    2000-02-02
6   42  1   2000-04-04  P   SFD 2000-05-01
7   42  1   2000-12-06  P   SFD 2001-01-03
8   43  1   2000-09-07  P   NONE    2000-09-21
9   51  1   2000-11-10  P   NONE    2000-11-28
10  53  1   2000-02-22  F   SFD 2000-02-22

После игры с методами в примере (используя like и regex) мне кажется, что эти методы могут фильтровать только значения в столбце индекса. Поэтому я изменил индекс:

df1_filter1 = df1.set_index('PHASE')


landuse_SUB_ID  TYPE    RECD_DATE   LAND_USE    CPACTIONDA
PHASE                   
P   24  1   2000-04-07  ROW 2000-05-04
P   24  1   2000-04-07  NONE    2000-05-04
P   25  1   2000-08-10  COMM    2000-09-08
F   34  1   2000-04-14  REC 2000-04-14
F   34  1   2000-04-14  SFD 2000-04-14
P   35  1   2000-01-20  NONE    2000-02-02
P   42  1   2000-04-04  SFD 2000-05-01
P   42  1   2000-12-06  SFD 2001-01-03
P   43  1   2000-09-07  NONE    2000-09-21
P   51  1   2000-11-10  NONE    2000-11-28
F   53  1   2000-02-22  SFD 2000-02-22

Теперь фрейм данных использует Phase в качестве индекса, я использовал метод like для фильтрации df1_filter1:

df1_filter1.filter(like = 'F', axis = 0)

Я получаю ошибку

«Ошибка значения: невозможно переиндексировать с дублированной оси»

Мне кажется, это очень простая операция, поэтому мне просто интересно, что я сделал неправильно, что вызвало эту ошибку. И каков будет лучший метод (наименьшее количество шагов и самый чистый код) для моего вопроса.

Ответы [ 2 ]

0 голосов
/ 14 сентября 2018

Как уже указывалось, для этой задачи filter не требуется.В ответе @ Александра используется loc.В качестве альтернативы вы также можете использовать query:

df1.query('PHASE == "F"')

    landuse_SUB_ID  TYPE   RECD_DATE PHASE LAND_USE  CPACTIONDA
3               34     1  2000-04-14     F      REC  2000-04-14
4               34     1  2000-04-14     F      SFD  2000-04-14
10              53     1  2000-02-22     F      SFD  2000-02-22

filter и у меня тоже отлично работает:

df1_filter1 = df1.set_index('PHASE')
df1_filter1.filter(like='F', axis=0)

       landuse_SUB_ID  TYPE   RECD_DATE LAND_USE  CPACTIONDA
PHASE                                                       
F                  34     1  2000-04-14      REC  2000-04-14
F                  34     1  2000-04-14      SFD  2000-04-14
F                  53     1  2000-02-22      SFD  2000-02-22

По поводу вашего вопроса оиспользование regex:

df2 = df1.set_index('LAND_USE')
df2.filter(regex="E$", axis=0)

          landuse_SUB_ID  TYPE   RECD_DATE PHASE  CPACTIONDA
LAND_USE                                                    
NONE                  24     1  2000-04-07     P  2000-05-04
NONE                  35     1  2000-01-20     P  2000-02-02
NONE                  43     1  2000-09-07     P  2000-09-21
NONE                  51     1  2000-11-10     P  2000-11-28

Здесь вы фильтруете все строки, заканчивающиеся на E.

То же, что вы могли бы достичь, например, выполнив:

df1[df1['LAND_USE'].str.endswith('E')]

   landuse_SUB_ID  TYPE   RECD_DATE PHASE LAND_USE  CPACTIONDA
1              24     1  2000-04-07     P     NONE  2000-05-04
5              35     1  2000-01-20     P     NONE  2000-02-02
8              43     1  2000-09-07     P     NONE  2000-09-21
9              51     1  2000-11-10     P     NONE  2000-11-28

Проблема с filter в том, что вы затем создаете индекс с неуникальными значениями, что обычно является плохой идеей.Итак, я бы пошел с .loc или .query.

0 голосов
/ 13 сентября 2018

filter может интуитивно показаться правильной функцией, но вы почти наверняка должны использовать loc для фильтрации ваших данных (в приведенной выше ссылке на примеры написано «Смотрите также: loc» вбольшая желтая коробка).В этом простом примере вы также можете использовать логическое индексирование:

>>> df1.loc[df1['PHASE'] == 'F']  # or boolean indexing via df1[df1['PHASE'] == 'F']
    landuse_SUB_ID  TYPE   RECD_DATE PHASE LAND_USE  CPACTIONDA
3               34     1  2000-04-14     F      REC  2000-04-14
4               34     1  2000-04-14     F      SFD  2000-04-14
10              53     1  2000-02-22     F      SFD  2000-02-22
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...