【问题标题】:Pandas + scikit-learn - how to apply 2D-array transformations to a DataFramePandas + scikit-learn - 如何将二维数组转换应用于 DataFrame
【发布时间】:2018-09-19 18:52:05
【问题描述】:

背景

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

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) 将数据逐列(一维数组)输入到缩放器中,其中缩放器需要一个二维数组。

按照herehere 的答案,我目前正在做:

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

但这似乎相当笨重且效率低下。另外,我觉得在极端情况下我会丢失 DataFrame 的元数据。

有没有更好的办法?

【问题讨论】:

    标签: pandas numpy scikit-learn


    【解决方案1】:

    您可以使用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
    

    【讨论】:

    • 谢谢,您知道这样的分配是否比使用构造函数效率更高/更低?从这个意义上说,iloc 也比 loc 更好?
    • @OmerB 不,对不起,我不了解性能。但是.loc 不能用于此,因为那是基于标签的索引。在“.loc”中,您不能指定条目索引。
    • 但我可以.loc[:,:] 甚至只是df[:]...它们可能都是等效的,但我会等着看是否有人对此有明确的答案...跨度>
    • @OmerB 他们在性能方面并不相同:stackoverflow.com/a/45983830/4016674
    【解决方案2】:

    考虑以下演示:

    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
    

    【讨论】:

      猜你喜欢
      • 2018-07-23
      • 2019-05-05
      • 2016-11-01
      • 1970-01-01
      • 2020-11-09
      • 2014-04-29
      • 2020-01-25
      • 2021-02-12
      • 2019-10-19
      相关资源
      最近更新 更多