如何通过pandas DataFrame中的另一行进行规范化?

时间:2015-08-21 15:21:48

标签: python pandas

我无法找到非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]

似乎我想将实验零参数精确到他们自己的列,以便于分割,但我无法使堆叠/旋转/连接正常工作。我使用.at并分配值来执行for循环,但感觉很错误。

接下来的步骤是规范化几个列并创建从(N,值),(N,value2),(N,other_values)等计算的upplower和更低的误差范围。

1 个答案:

答案 0 :(得分: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