1
votes

Filtrer la trame de données en fonction de la fréquence d'une valeur dans une ligne

J'ai examiné de nombreuses questions similaires aux miennes, mais je n'ai pas encore trouvé de solution claire à ce que je recherche (je serais heureux si vous créez un lien vers une réponse s'il s'agit d'une question en double ou de ce type a déjà été répondu).

J'ai un bloc de données comme celui-ci:

col_0 | col_1 | col_2 | col_3 | col_4 | col_5
---------------------------------------------
  0.3    0.4      1       1       1       1
  0.1     1      0.3      1       1       1    

Je veux simplement filtrer / exclure les lignes dans lesquelles la fréquence de 1 est plus qu'un seuil (généralement une fréquence / nombre basé sur une condition), disons 4 ici. En conséquence, je veux une trame de données comme celle-ci dans ma sortie:

col_0 | col_1 | col_2 | col_3 | col_4 | col_5
---------------------------------------------
  0.2     1       1       1       1       1
  0.3    0.4      1       1       1       1
  0.1     1      0.3      1       1       1    

Ma question clé est donc: comment pouvons-nous exclure des lignes dans une trame de données en fonction de la fréquence / compter une valeur spécifique en eux. Et, idéalement, je souhaite spécifier une plage de colonnes dans une ligne, par exemple la fréquence d'une valeur de l'index de colonne 0 à 4 (non basée sur le nom de la colonne), ce qui, à mon avis, n'est pas si difficile.


0 commentaires

3 Réponses :


1
votes

Cela fonctionne-t-il?

df.loc[(df==1).sum(axis=1).between(0,4),:]


7 commentaires

Je ne pense pas que ce soit syntaxiquement correct: Référence d'attribut non résolue 'sum' pour la classe 'bool'


Pourquoi utiliser between au lieu de chier ?


@Pedram c'est syntaxiquement correct, je l'ai testé de mon côté. Vous n'avez pas donné un exemple reproductible minimal et ce problème est externe à ce que vous avez répertorié dans le problème


@roganjosh, OP recherché entre une plage donc entre est plus général je suppose?


Assez juste :) @Pedram df = pd.DataFrame ({'a': [1, 0.2, 1, 1], 'b': [1, 0.2, 0.3, 0.4], 'c': [1 , 1, 0.5, 0.6]}) n'est pas un effort énorme, par exemple, pour avoir inclus dans votre question, pour laquelle cette approche fonctionne. Si vous ne nous donnez pas les outils pour créer un DF représentatif, ne soyez pas surpris si les réponses ne sont pas plug-and-play


@ thushv89 quelle que soit la syntaxe, juste pour m'assurer que je comprends votre code, dans quelle partie du code vous vérifiez la fréquence?


@Pedram, ce sera sum () . Donc, fondamentalement, nous créons d'abord un filtre (par exemple (df == 1) , puis faisons sum over axis = 1, ce qui donne la fréquence de la valeur 1 sur les colonnes.



0
votes

Vous pouvez utiliser:

df[df.eq(1).sum(axis=1).le(4)]

   col_0  col_1  col_2  col_3  col_4  col_5
1    0.3    0.4    1.0      1      1      1
2    0.1    1.0    0.3      1      1      1


0 commentaires

0
votes

Peut-être pas le moyen le plus rapide, mais peut-être facile de voir ce qui se passe:

import pandas as pd

d = {'col_0' : [ 0.2, 0.3, 0.1], 
'col_1' : [ 1, 0.4, 1], 
'col_2' : [ 1, 1, 0.3], 
'col_3' : [ 1, 1, 1], 
'col_4' : [ 1, 1, 1], 
'col_5' : [ 1, 1, 1]}

df = pd.DataFrame(d)
def apply_freq_filter(df, value, frequency, col_start, col_end):
    f = df.iloc[:,col_start:col_end+1].apply(pd.value_counts, axis=1)
    f = f[value] <= frequency
    return df[f]

df = apply_freq_filter(df, 1, 4, 0, 5)
print(df)


3 commentaires

Je dirais que c'est loin moins lisible que les deux réponses existantes


Mais je crois avant tout parce qu'il offre plus de généralité que les autres. Si vous incluez la colonne de début, la colonne de fin, la valeur de variable et la fréquence dans les autres solutions, cela peut devenir plus difficile à lire. Mais point pris!


Je suis un peu assis sur la clôture parce que je vois le point d'extensibilité, mais je pense que c'est orthogonal à la prémisse du traitement rapide des données, qui s'appliquent jette juste à la poubelle. Les autres approches pourraient encore être regroupées dans une fonction :)