2016-10-17 8 views
5

Ich möchte negative Werte durch nan für nur bestimmte Spalten ersetzen. Der einfachste Weg könnte sein:Pandas: Wie können mehrere Spalten bedingt zugewiesen werden?

for col in ['a', 'b', 'c']: 
    df.loc[df[col ] < 0, col] = np.nan 

df viele Spalten haben könnte, und ich will nur diese auf bestimmte Spalten tun.

Gibt es eine Möglichkeit, dies in einer Zeile zu tun? Scheint so, als ob das einfach sein sollte, aber ich konnte es nicht herausfinden.

Antwort

11

Ich glaube nicht, Sie als dies viel einfacher erhalten werden:

>>> df = pd.DataFrame({'a': np.arange(-5, 2), 'b': np.arange(-5, 2), 'c': np.arange(-5, 2), 'd': np.arange(-5, 2), 'e': np.arange(-5, 2)}) 
>>> df 
    a b c d e 
0 -5 -5 -5 -5 -5 
1 -4 -4 -4 -4 -4 
2 -3 -3 -3 -3 -3 
3 -2 -2 -2 -2 -2 
4 -1 -1 -1 -1 -1 
5 0 0 0 0 0 
6 1 1 1 1 1 
>>> df[df[cols] < 0] = np.nan 
>>> df 
    a b c d e 
0 NaN NaN NaN -5 -5 
1 NaN NaN NaN -4 -4 
2 NaN NaN NaN -3 -3 
3 NaN NaN NaN -2 -2 
4 NaN NaN NaN -1 -1 
5 0.0 0.0 0.0 0 0 
6 1.0 1.0 1.0 1 1 
6

Verwendung loc und where

cols = ['a', 'b', 'c'] 
df.loc[:, cols] = df[cols].where(df[cols].where.ge(0), np.nan) 

Demonstration

df = pd.DataFrame(np.random.randn(10, 5), columns=list('abcde')) 
df 

enter image description here

cols = list('abc') 
df.loc[:, cols] = df[cols].where(df[cols].ge(0), np.nan) 
df 

enter image description here


Man könnte es beschleunigen mit numpy

df[cols] = np.where(df[cols] < 0, np.nan, df[cols]) 

das Gleiche zu tun.


Timing

def gen_df(n): 
    return pd.DataFrame(np.random.randn(n, 5), columns=list('abcde')) 

da Zuordnung ist ein wichtiger Teil dieser, ich die df von Grund auf jede Schleife erstellen. Ich habe auch das Timing für df Erstellung hinzugefügt.

für n = 10000

enter image description here

für n = 100000

enter image description here

+0

@jezrael netter Fang – piRSquared

5

Hier ist eine Art und Weise:

df[df.columns.isin(['a', 'b', 'c']) & (df < 0)] = np.nan 
4

Sie können np.where verwenden

In [47]: 
df = pd.DataFrame(np.random.randn(5,5), columns=list('abcde')) 
df 

Out[47]: 
      a   b   c   d   e 
0 0.616829 -0.933365 -0.735308 0.665297 -1.333547 
1 0.069158 2.266290 -0.068686 -0.787980 -0.082090 
2 1.203311 1.661110 -1.227530 -1.625526 0.045932 
3 -0.247134 -1.134400 0.355436 0.787232 -0.474243 
4 0.131774 0.349103 -0.632660 -1.549563 1.196455 

In [48]:  
df[['a','b','c']] = np.where(df[['a','b','c']] < 0, np.NaN, df[['a','b','c']]) 
df 

Out[48]: 
      a   b   c   d   e 
0 0.616829  NaN  NaN 0.665297 -1.333547 
1 0.069158 2.266290  NaN -0.787980 -0.082090 
2 1.203311 1.661110  NaN -1.625526 0.045932 
3  NaN  NaN 0.355436 0.787232 -0.474243 
4 0.131774 0.349103  NaN -1.549563 1.196455 
1

Wenn es ein Einzeiler sein muss: dies erreichen

df[['a', 'b', 'c']] = df[['a', 'b', 'c']].apply(lambda c: [x>0 and x or np.nan for x in c]) 
3

Sure Wählen Sie einfach die gewünschten Spalten aus der Maske:

(df < 0)[['a', 'b', 'c']] 

Sie können verwenden diese Maske in df[(df < 0)[['a', 'b', 'c']]] = np.nan.

Verwandte Themen