Фильтровать повторяющиеся строки в панде DataFrame - PullRequest
1 голос
/ 02 октября 2019

Я пытаюсь отфильтровать строки DataFrame панд на основе некоторых условий, и у меня возникают трудности с этим. DataFrame выглядит так:

import pandas as pd
import numpy as np

df = pd.DataFrame({'cus_id': [1111, 2222, 2222, 3333, 4444, 4444, 4444, 5555, 5555], 
                  'cus_group' : [1, 1, 0, 0, 1, 1, 0, 0, 0]})

print(df)

   cus_id  cus_group
0    1111          1
1    2222          1
2    2222          0
3    3333          0
4    4444          1
5    4444          1
6    4444          0
7    5555          0
8    5555          0

Выбор, который я хотел бы применить, следующий:

Для всех cus_id , которые появляются более одного раза (то есть для всехдубликаты cus_id ), оставляйте только те, в которых cus_group равен 1. Внимание: если cus_id появляется более одного раза, но принадлежит только группе 0,мы сохраняем все экземпляры этого клиента.

Визуально, результирующий DataFrame, который я хочу, выглядит примерно так:

   cus_id  cus_group
0    1111          1
1    2222          1
2    3333          0
3    4444          1
4    4444          1
5    5555          0
6    5555          0

Как вы можете видеть для cus_id = 5555, дажехотя он появляется дважды, мы сохраняем обе записи, поскольку он принадлежит только группе 0. Я пробовал несколько вещей, используя метод duplicated (), но безуспешно. Любая дополнительная помощь будет принята с благодарностью.


РЕДАКТИРОВАТЬ: Решение, предоставленное jezrael отлично работает для примера выше. Я заметил, что в реальном DataFrame, который я использую, есть случаи, когда клиенты связаны с группой NaN. Например:

import pandas as pd
import numpy as np

df = pd.DataFrame({'cus_id': [1111, 2222, 2222, 3333, 4444, 4444, 4444, 5555, 5555, 6666, 7777, 7777, ], 
                  'cus_group' : [1, 1, 0, 0, 1, 1, 0, 0, 0, np.nan, np.nan, np.nan]})

print(df)

    cus_id  cus_group
0     1111        1.0
1     2222        1.0
2     2222        0.0
3     3333        0.0
4     4444        1.0
5     4444        1.0
6     4444        0.0
7     5555        0.0
8     5555        0.0
9     6666        NaN
10    7777        NaN
11    7777        NaN

При использовании решения jezrael эти клиенты отбрасываются. Существует ли быстрое решение для сохранения ALL (включая дубликаты) таких случаев в окончательном DataFrame? Визуально (после фильтрации):

    cus_id  cus_group
0     1111        1.0
1     2222        1.0
2     3333        0.0
3     4444        1.0
4     4444        1.0
5     5555        0.0
6     5555        0.0
7     6666        NaN
8     7777        NaN
9     7777        NaN

Ответы [ 2 ]

1 голос
/ 02 октября 2019

Быстрое решение будет отфильтровано NaN группы, а затем добавьте в таблицу:

df = df[df.groupby('cus_id')['cus_group'].transform('nunique').eq(1)
     | df['cus_group'].eq(1)].append(df[df['cus_group'].isnull()])
   print(df)

Ответ:

    cus_id  cus_group
0     1111        1.0
1     2222        1.0
3     3333        0.0
4     4444        1.0
5     4444        1.0
7     5555        0.0
8     5555        0.0
9     6666        NaN
10    7777        NaN
11    7777        NaN
1 голос
/ 02 октября 2019

Одна идея - отфильтровать все 0 группы со сравнением 0 и GroupBy.transform с GroupBy.all и цепочкой с | для побитового OR для 1 строк:

df = df[df['cus_group'].eq(0).groupby(df['cus_id']).transform('all') | df['cus_group'].eq(1)]

Или, если возможно, только значения 1 и 0 в столбце cus_group:

df = df[df.groupby('cus_id')['cus_group'].transform('nunique').eq(1) | df['cus_group'].eq(1)]

print(df)
   cus_id  cus_group
0    1111          1
1    2222          1
3    3333          0
4    4444          1
5    4444          1
7    5555          0
8    5555          0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...