Фильтр по комбинации из трех столбцов первых значений - PullRequest
2 голосов
/ 30 сентября 2019

У меня есть отсортированный Dataframe с 4 столбцами, как показано ниже. Я пытаюсь отфильтровать свой фрейм данных таким образом, чтобы для каждой комбинации (Var1, Var2, Var3) я оставил 2 первых значения disctint для Var4. Например, первая комбинация (Var1, Var2, Var3), которую я имею в моем Dataframe, - (A, B, C). Два первых отличных значения для этой комбинации - значение_1 и значение_2. Вторая комбинация (Var1, Var2, Var3) - (A, C, C). У меня есть только один тип значения для этой комбинации, значение_14. Etc ...

Ввод:

       Var1  Var2  Var3  Var4
    1     A    B      C  value_1
    2     A    B      C  value_1
    3     A    B      C  value_1
    4     A    B      C  value_1
    5     A    B      C  value_2
    6     A    B      C  value_2
    7     A    B      C  value_3
    8     A    B      C  value_3
    9     A    B      C  value_3
    10    A    B      C  value_4
   11     A    C      C  value_14
   12     A    C      C  value_14
   13     A    C      C  value_14
   14     A    C      C  value_14
   15     B    B      C  value_21
   16     B    B      C  value_21
   17     B    B      C  value_32
   18     B    B      C  value_32
   19     B    B      C  value_33
   20     B    B      C  value_43

Ввод:

       Var1  Var2  Var3  Var4
    1     A    B      C  value_1
    2     A    B      C  value_1
    3     A    B      C  value_1
    4     A    B      C  value_1
    5     A    B      C  value_2
    6     A    B      C  value_2
   11     A    C      C  value_14
   12     A    C      C  value_14
   13     A    C      C  value_14
   14     A    C      C  value_14
   15     B    B      C  value_21
   16     B    B      C  value_21
   17     B    B      C  value_32
   18     B    B      C  value_32

Обратите внимание, что мой фрейм данных содержит 5 миллионов строк. Пока я нашел решение с использованием цикла, но это занимает почти час.

Ответы [ 3 ]

3 голосов
/ 30 сентября 2019

ngroup обозначает группу, затем мы гарантируем, что каждая группа начинается с 0, вычитая мин. Тогда простая маска.

s = df.groupby([*df], sort=False).ngroup()  #sort = False keeps ordering of Val4
s = s - s.groupby([df.Var1, df.Var2, df.Var3]).transform('min')

df[s.le(1)]

   Var1 Var2 Var3      Var4
1     A    B    C   value_1
2     A    B    C   value_1
3     A    B    C   value_1
4     A    B    C   value_1
5     A    B    C   value_2
6     A    B    C   value_2
11    A    C    C  value_14
12    A    C    C  value_14
13    A    C    C  value_14
14    A    C    C  value_14
15    B    B    C  value_21
16    B    B    C  value_21
17    B    B    C  value_32
18    B    B    C  value_32
3 голосов
/ 30 сентября 2019

Мы можем использовать

df[df.groupby(['Var1','Var2','Var3'])['Var4'].apply(lambda x : x.groupby(x).ngroup()<2)]

Out[106]: 
   Var1 Var2 Var3      Var4
1     A    B    C   value_1
2     A    B    C   value_1
3     A    B    C   value_1
4     A    B    C   value_1
5     A    B    C   value_2
6     A    B    C   value_2
11    A    C    C  value_14
12    A    C    C  value_14
13    A    C    C  value_14
14    A    C    C  value_14
15    B    B    C  value_21
16    B    B    C  value_21
17    B    B    C  value_32
18    B    B    C  value_32
0 голосов
/ 30 сентября 2019

Позвольте использовать этот метод:

df.drop_duplicates(['Var1','Var2','Var3','Var4'])\
  .groupby(['Var1','Var2','Var3']).head(2)\
  .merge(df, on=['Var1','Var2','Var3','Var4'])

Вывод:

   Var1 Var2 Var3      Var4
0     A    B    C   value_1
1     A    B    C   value_1
2     A    B    C   value_1
3     A    B    C   value_1
4     A    B    C   value_2
5     A    B    C   value_2
6     A    C    C  value_14
7     A    C    C  value_14
8     A    C    C  value_14
9     A    C    C  value_14
10    B    B    C  value_21
11    B    B    C  value_21
12    B    B    C  value_32
13    B    B    C  value_32
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...