如何在pandas DataFrame中通过另一行进行归一化?

6
我找不到不使用for循环版本的代码。假设这是我的输入:
In [94]: df
Out[94]: 
        N  experiment   color  value    value2
0  145000           0     red   0.30  0.363953
1   14000           1     red   0.31  0.218978
2   13000           2     red   0.29  0.948070
3   15000           0  yellow   0.31  0.620201
4    1200           1  yellow   0.32  0.567513
5    1400           2  yellow   0.31  0.318197
6   40000           0   green   0.29  0.947226
7    3000           1   green   0.31  0.084243
8    7000           2   green   0.32  0.961020

[9 rows x 5 columns]

实验0是我的对照组。我为各种颜色执行了这个实验。我想通过匹配颜色的实验0来标准化所有行。
In [104]: df
Out[104]: 
        N  experiment   color  value    value2  scaled_value  scaled_value2
0  145000           0     red   0.30  0.363953      1.000000       1.000000
1   14000           1     red   0.31  0.218978      1.033333       0.590786
2   13000           2     red   0.29  0.948070      0.966667       2.604732
3   15000           0  yellow   0.31  0.620201      1.000000       1.000000
4    1200           1  yellow   0.32  0.567513      1.032258       0.914220
5    1400           2  yellow   0.31  0.318197      1.000000       0.512737
6   40000           0   green   0.29  0.947226      1.000000       1.000000
7    3000           1   green   0.31  0.084243      1.068966       0.088680
8    7000           2   green   0.32  0.961020      1.103448       1.014541

[9 rows x 7 columns]

似乎我想将实验零参数提取到它们自己的列中以便于进行简单的除法,但我无法正确地进行堆叠/透视/连接。我使用了for循环和.at来分配值,但感觉这样做是错误的。
接下来的步骤将是对多个列进行归一化,并从(N,value),(N,value2),(N,other_values)等计算上限和下限误差边界。

看一下 sklearnMinMaxScaler;我想他们已经优化了向量操作。而且我很确定你可以将 pandas 数据输入其中。http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html - Ryan
@Ryan,那不是用于缩放单个列/数组中的值吗?当我说归一化时,我并不是指向量范围(0,1),而是每个值都被外部值除。 - physicsmichael
1个回答

4

一种方法是使用 transform(这里使用 idxmin,虽然还有很多其他选择)来获取我们想要用作分母的行的索引:

>>> ii = df.groupby("color")["experiment"].transform("idxmin")
>>> cols = ["value", "value2"]
>>> new_cols = (df.loc[:,cols] /df.loc[ii, cols].values)
>>> df.join(new_cols.rename(columns=lambda x: "scaled_" + x))
        N  experiment   color  value    value2  scaled_value  scaled_value2
0  145000           0     red   0.30  0.363953      1.000000       1.000000
1   14000           1     red   0.31  0.218978      1.033333       0.601666
2   13000           2     red   0.29  0.948070      0.966667       2.604924
3   15000           0  yellow   0.31  0.620201      1.000000       1.000000
4    1200           1  yellow   0.32  0.567513      1.032258       0.915047
5    1400           2  yellow   0.31  0.318197      1.000000       0.513055
6   40000           0   green   0.29  0.947226      1.000000       1.000000
7    3000           1   green   0.31  0.084243      1.068966       0.088937
8    7000           2   green   0.32  0.961020      1.103448       1.014563

逐步进行,首先我们找到分母的指数:

>>> ii = df.groupby("color")["experiment"].transform("idxmin")
>>> ii
0    0
1    0
2    0
3    3
4    3
5    3
6    6
7    6
8    6
dtype: int64

然后我们可以使用这个来索引帧:
>>> df.loc[ii, cols]
   value    value2
0   0.30  0.363953
0   0.30  0.363953
0   0.30  0.363953
3   0.31  0.620201
3   0.31  0.620201
3   0.31  0.620201
6   0.29  0.947226
6   0.29  0.947226
6   0.29  0.947226

由于我们需要自己处理对齐,因此我们需要调用.values来降到底层数组 - 否则pandas将尝试根据索引正确对齐。

然后我们进行除法操作:

>>> (df.loc[:,cols] /df.loc[ii, cols].values)
      value    value2
0  1.000000  1.000000
1  1.033333  0.601666
2  0.966667  2.604924
3  1.000000  1.000000
4  1.032258  0.915047
5  1.000000  0.513055
6  1.000000  1.000000
7  1.068966  0.088937
8  1.103448  1.014563

最后将它们合并,并重新命名新列:

>>> df.join(new_cols.rename(columns=lambda x: "scaled_" + x))
        N  experiment   color  value    value2  scaled_value  scaled_value2
0  145000           0     red   0.30  0.363953      1.000000       1.000000
1   14000           1     red   0.31  0.218978      1.033333       0.601666
2   13000           2     red   0.29  0.948070      0.966667       2.604924
3   15000           0  yellow   0.31  0.620201      1.000000       1.000000
4    1200           1  yellow   0.32  0.567513      1.032258       0.915047
5    1400           2  yellow   0.31  0.318197      1.000000       0.513055
6   40000           0   green   0.29  0.947226      1.000000       1.000000
7    3000           1   green   0.31  0.084243      1.068966       0.088937
8    7000           2   green   0.32  0.961020      1.103448       1.014563

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接