2016-10-17 38 views
5

我想用nan來代替負數值僅用於某些列。最簡單的方法可能是:熊貓:如何有條件地分配多列?

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

df可以有很多列,我只希望這樣做是爲了特定的列。

有沒有辦法在一行中做到這一點?似乎這應該很容易,但我一直無法弄清楚。

回答

11

我不認爲你會得到比這更簡單:

>>> 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

使用locwhere

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

示範

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


你可以加快它與numpy的

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

做同樣的事情。


定時

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

因爲分配是這方面的一個重要組成部分,我從頭創建df每個迴路。我還添加了創建時間爲df

n = 10000

enter image description here

n = 100000

enter image description here

+0

@jezrael nice catch – piRSquared

5

這裏有一個辦法:

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

您可以使用np.where要實現這一點:

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

如果它必須是一個班輪:

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

當然,只需從面罩中選擇所需的色譜柱:

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

您可以使用這個面具在df[(df < 0)[['a', 'b', 'c']]] = np.nan