2016-07-23 155 views
5

如何將數據幀中的所有數值乘以常數而不必明確指定列名?例如:pandas,將數據幀中的所有數值乘以常數

In [13]: df = pd.DataFrame({'col1': ['A','B','C'], 'col2':[1,2,3], 'col3': [30, 10,20]}) 

In [14]: df 
Out[14]: 
    col1 col2 col3 
0 A  1 30 
1 B  2 10 
2 C  3 20 

我試圖df.multiply但它通過連接他們幾次影響字符串值也是如此。

In [15]: df.multiply(3) 
Out[15]: 
    col1 col2 col3 
0 AAA  3 90 
1 BBB  6 30 
2 CCC  9 60 

有沒有一種方法來保持字符串值完好無損,而只用一個常數乘以數值?

+0

是否有任何理由避免列名? – ganesshkumar

+0

帶有混合文本和數字字段的大型數據框。 @ganesshkumar – CentAu

回答

6

可以使用select_dtypes()包括number D型或排除的object所有列和datetime64 dtypes:

演示:

In [162]: df 
Out[162]: 
    col1 col2 col3  date 
0 A  1 30 2016-01-01 
1 B  2 10 2016-01-02 
2 C  3 20 2016-01-03 

In [163]: df.dtypes 
Out[163]: 
col1   object 
col2    int64 
col3    int64 
date datetime64[ns] 
dtype: object 

In [164]: df.select_dtypes(exclude=['object', 'datetime']) * 3 
Out[164]: 
    col2 col3 
0  3 90 
1  6 30 
2  9 60 

或更好的解決方案(三)ayhan

df[df.select_dtypes(include=['number']).columns] *= 3 

來自docs

要選擇所有的數字類型使用numpy的D型numpy.number

+2

要對原始數據幀進行操作,可以將其修改爲:'df [df.select_dtypes(include = ['number'])。columns] * = 3' – ayhan

+1

@ayhan,謝謝!我已經將你的解決方案添加到我的答案中,因爲它可以幫助那些不閱讀評論的人...... :) – MaxU

+0

我只是想知道我最近有一種隨意的想法:是否公平地回答熊貓問題NumPy funcs?我的意思是我不介意,但我猜測OPs也不會,並且也可以訪問NumPy,至少如果我記得安裝熊貓庫的時候;)另外,由於pandas在內部使用NumPy,這看起來像是黑客攻擊/作弊?順便提一下,我指的是我在熊貓上的帖子。 – Divakar

2

對方回答指定了如何乘只有數字列。以下是如何更新:

df = pd.DataFrame({'col1': ['A','B','C'], 'col2':[1,2,3], 'col3': [30, 10,20]}) 

s = df.select_dtypes(include=[np.number])*3 

df[s.columns] = s 

print (df) 

    col1 col2 col3 
0 A  3 90 
1 B  6 30 
2 C  9 60 
4

一種方式是得到dtypes,配合他們對objectdatetime dtypes,並用口罩排斥他們,就像這樣 -

df.ix[:,~np.in1d(df.dtypes,['object','datetime'])] *= 3 

採樣運行 -

In [273]: df 
Out[273]: 
    col1 col2 col3 
0 A  1 30 
1 B  2 10 
2 C  3 20 

In [274]: df.ix[:,~np.in1d(df.dtypes,['object','datetime'])] *= 3 

In [275]: df 
Out[275]: 
    col1 col2 col3 
0 A  3 90 
1 B  6 30 
2 C  9 60 
1

即使在列中的混合類型上,它也可以工作,但可能會在大型數據框上變慢。

def mul(x, y): 
    try: 
     return pd.to_numeric(x) * y 
    except: 
     return x 

df.applymap(lambda x: mul(x, 3))