Pandas + scikit-learn - 如何将2D数组转换应用于DataFrame

时间:2018-04-10 08:22:51

标签: pandas numpy scikit-learn

背景

scikit-learn API基于有状态对象,它将2D numpy数组作为输入,计算转换(在内部,在对象内),然后将其应用于其他2D数组。 e.g:

arr = np.arange(4).reshape(2,2)
scaler = sklearn.preprocessing.StandardScaler()
scaler.fit(arr) # scaler state has changed, nothing returns
scaler.transform(arr) # a transformed version of arr returns

我的问题

我想对存储在pandas DataFrame中的数据应用转换,并将转换后的数据放回到同一个DataFrame中。

问题是df.apply(scaler.transform)将数据逐列(1D数组)提供给缩放器,其中scaler需要2D数组。

根据答案herehere,我目前正在做:

transformed_array = scaler.transform(df.values)
transformed_df = pd.DataFrame(data=transformed_array, index=df.index, columns=df.columns)

但这似乎相当笨重而且效率低下。此外,我感觉还有一个角落,我将失去DataFrame的元数据。

有更好的方法吗?

2 个答案:

答案 0 :(得分:0)

您可以使用iloc[:,:]

根据documentation

  

Pandas提供了一套方法来获得纯粹的整数   基于索引。语义紧跟python和numpy切片。   这些是基于0的索引。切片时,起始界限是   包括在内,而上限则被排除在外。请注意,设置也可以。

示例:

df = pd.DataFrame([[1, 2.], [3, 4.]], columns=['a', 'b'])
df2 = pd.DataFrame([[3, 4.], [5, 6.]], columns=['c', 'd'])

df.iloc[:,:]=df2.values
print(df)
     a    b
0  3.0  4.0
1  5.0  6.0

所以在你的情况下,它将是:

df.iloc[:,:] = scaler.transform(df.values) # On an already fitted scaler

答案 1 :(得分:0)

考虑以下演示:

In [198]: df = (pd.DataFrame(np.random.randint(10**5, size=(5,3)), columns=list('abc'))
                  .assign(d=list('abcde')))

In [199]: df
Out[199]:
       a      b      c  d
0  17821  80092  11803  a
1  91198  19663  78665  b
2  77674  46347  72550  c
3  67390  63699  16347  d
4  50445  31346  95608  e

In [200]: cols = ['a','b','c']

In [201]: df[cols] = scaler.fit_transform(df[cols])

In [202]: df
Out[202]:
          a         b         c  d
0 -1.701325  1.466854 -1.259806  a
1  1.196186 -1.315108  0.690414  b
2  0.662151 -0.086660  0.512053  c
3  0.256056  0.712172 -1.127267  d
4 -0.413068 -0.777259  1.184605  e