2 votes

Filtrer par combinaison de trois colonnes les n premières valeurs

J'ai un Dataframe trié avec 4 colonnes comme ci-dessous. J'essaie de filtrer ma base de données de telle sorte que pour chaque combinaison de (Var1, Var2, Var3), je garde les 2 premières valeurs distinctes pour Var4. Par exemple, la première combinaison de (Var1, Var2, Var3) que j'ai dans mon Dataframe est (A, B, C). Les deux premières valeurs distinctes de cette combinaison sont value_1 et value_2. La deuxième combinaison de (Var1, Var2, Var3) est (A, C, C). Je n'ai qu'un seul type de valeur pour cette combinaison, à savoir la valeur_14. Etc...

Entrée :

       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

Sortie :

       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

Notez que mon dataframe contient 5 millions de lignes. J'ai trouvé une solution en utilisant une boucle jusqu'à présent mais cela prend presque une heure.

3voto

W-B Points 94428

Nous pouvons utiliser

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

3voto

ALollz Points 23271

ngroup étiquette le groupe, alors nous nous assurons que chaque groupe commence à 0 en soustrayant le min. Ensuite, un simple masque.

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

0voto

Scott Boston Points 48995

Utilisons cette méthode :

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

Sortie :

   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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X