3 votes

Recodage des colonnes basé sur le nombre de distinctions

J'ai un cadre de données de panda comme ça :

import pandas as pd

data = {'VAR1': ['A', 'A', 'A', 'A','B', 'B'],

'VAR2': ['C', 'V', 'C', 'C','V', 'D']}

frame = pd.DataFrame(data)

Fondamentalement, je dois recoder chaque variable. Le recodage fonctionnerait comme suit : calculer un compte de valeurs distinctes pour chaque colonne, et si le compte est supérieur ou égal à un seuil, conserver la valeur d'origine, sinon définir une nouvelle valeur de "X". Si le seuil était de 3, voici à quoi cela devrait ressembler.

data2 = {'VAR3': ['A', 'A', 'A', 'A','X', 'X'],

'VAR4': ['C', 'X', 'C', 'C','X', 'X']}

frame2 = pd.DataFrame(data2)

Et voici le résultat souhaité, avec les données originales fusionnées aux données recodées.

pd.merge(frame, frame2, left_index=True, right_index=True)

Je suis novice en Python et bien que le livre Python for Data Analysis m'aide vraiment, je n'arrive toujours pas à trouver comment obtenir le résultat souhaité de manière simple. Toute aide serait la bienvenue !

4voto

Dan Allan Points 6172

Prenez chaque colonne individuellement. Regroupez-les par valeur, et utilisez la fonction filter sur les groupes pour remplacer tout groupe avec moins de 3 valeurs par NaN . Ensuite, remplacez ces NaNs con X .

Vous pourriez faire tout cela dans une seule liste de compréhension, mais pour plus de clarté, j'ai défini un fichier recode qui fait toutes les choses importantes.

In [38]: def recode(s, threshold):
   ....:     return s.groupby(s).filter(lambda x: x.count() >= threshold, dropna=False).fillna(value='X')
   ....: 

Appliquer à chaque colonne, puis réassembler les colonnes en un nouveau DataFrame.....

In [39]: frame2 = pd.concat([recode(frame[col], 3) for col in frame], axis=1)

In [40]: frame2
Out[40]: 
  VAR1 VAR2
0    A    C
1    A    X
2    A    C
3    A    C
4    X    X
5    X    X

Et, pour être sûr, vous pouvez fusionner les images originales et les images recodées, comme vous l'avez exprimé dans votre question :

In [27]: pd.merge(frame, frame2, left_index=True, right_index=True)
Out[27]: 
  VAR1_x VAR2_x VAR1_y VAR2_y
0      A      C      A      C
1      A      V      A      X
2      A      C      A      C
3      A      C      A      C
4      B      V      X      X
5      B      D      X      X

Edit : Utilisez cette solution de contournement équivalente pour les versions de pandas < 0.12 :

def recode(s, threshold):
    b = s.groupby(s).transform(lambda x: x.count() >= threshold).astype('bool') # True/False
    s[~b] = 'X'
    return s

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