2015-12-03 2 views
1

A partir de cette trame de données simple, df:pandas géants - dataframe masque par nom de colonne

col1,col2 
1,3 
2,1 
3,8 

je voudrais appliquer une mask booléenne en fonction du nom de la colonne. Je sais qu'il est facile pour les valeurs:

mask = df <= 1 

df = df[mask] 

qui retourne:

masque:

col1 col2 
0 True False 
1 False True 
2 False False 

df:

col1 col2 
0  1 NaN 
1 NaN  1 
2 NaN NaN 

comme prévu. Maintenant, je voudrais obtenir un masque booléen basé sur le nom de la colonne, quelque chose comme:

mask = df == df['col_1'] 

qui doit retourner:

masque

col1 col2 
0 True False 
1 True False 
2 True False 

EDIT:

Cela semble bizarre , mais j'ai besoin de ce genre de masques pour filtrer plus tard par des heatmaps seaborn colonnes.

+2

Désolé mais pourquoi montrer les cols qui ne répondent pas aux critères? Vous pouvez filtrer en faisant 'df.filter (['col1'])' ou 'df [df.columns [df.colonnes == 'col1]] ' – EdChum

+0

@EdChum merci! En fait, les valeurs 'True' appartiennent aux valeurs correspondant au nom de la colonne que je voudrais sélectionner. –

+1

Eh bien, vous pouvez simplement faire 'df.columns == 'col1' qui va retourner un masque booléen – EdChum

Répondre

6

Comme indiqué dans les commentaires, les situations où vous auriez besoin d'obtenir un "masque" comme cela semble rare (et les chances sont, vous n'êtes pas dans l'un d'eux). Par conséquent, il n'y a probablement pas de solution «intégrée» pour eux dans Pandas.

Néanmoins, vous pouvez obtenir ce dont vous avez besoin, en utilisant un hack comme suit, par exemple:

mask = (df == df) & (df.columns == 'col_1') 

Mise à jour:. Comme indiqué dans les commentaires, si votre trame de données contient des valeurs nulles, le masque calculé de cette manière sera toujours False aux emplacements correspondants. Si cela est un problème, l'option la plus sûre est:

mask = ((df == df) | df.isnull()) & (df.columns == 'col_1') 
+0

Merci, mais il retourne un mauvais masque, peuplé uniquement avec 'False' –

+0

Évidemment, vous devez remplacer le nom de colonne correct. Je n'ai aucune idée s'il devrait être 'col1' ou' col_1', ou n'importe quoi d'autre. –

+1

Ah oui désolé ma faute !! ça fonctionne merci! –

1

Vous pouvez transposer votre dataframe que de comparer avec les colonnes, puis transposent en arrière. Un peu exemple bizarre, mais travailler:

import pandas as pd 
from io import StringIO 

data = """ 
col1,col2 
1,3 
2,1 
3,8 
""" 

df = pd.read_csv(StringIO(data)) 
mask = (df.T == df['col1']).T 

In [176]: df 
Out[176]: 
    col1 col2 
0  1  3 
1  2  1 
2  3  8 


In [178]: mask 
Out[178]: 
    col1 col2 
0 True False 
1 True False 
2 True False 

EDIT

J'ai trouvé une autre réponse pour cela, vous pouvez utiliser la méthode isin:

In [41]: df.isin(df.col1) 
Out[41]: 
    col1 col2 
0 True False 
1 True False 
2 True False 

EDIT2

Comme @ DSM montre dans le commentaire que ces deux cas ne fonctionnent pas correctement. Donc, vous devriez utiliser @KT. méthode. Mais .. Jouons plus avec transpose:

df.col2 = df.col1 

In [149]: df 
Out[149]: 
    col1 col2 
0  1  1 
1  2  2 
2  3  3 

In [147]: df.isin(df.T[df.columns == 'col1'].T) 
Out[147]: 
    col1 col2 
0 True False 
1 True False 
2 True False 
+1

'df.isin (df.col1)' ne fonctionne ici que par coïncidence - essayez-le avec 'df [" col2 "] = [3,2,8]', par exemple. En fait, à y penser, votre méthode de transposition ne fonctionne que par coïncidence. : -/Essayez avec 'df [" col2 "] = df [" col1 "]'. – DSM

+0

@DSM Oui, vous avez raison ... Merci, je vais essayer de trouver un autre moyen –