【问题标题】:Normalize values in a multiindex dataframe?规范化多索引数据框中的值?
【发布时间】:2013-07-14 16:04:53
【问题描述】:

如何规范化多索引数据框?

假设我有数据框:

d = pd.DataFrame([["a",1,3],["a",2,2],["b",4,4],["b",5,8]], 
                  columns=["name","value1","value2"])

如何计算每个“名称”的标准化值?

我知道如何规范化基本数据框:

d = (d-d.mean(axis=0))/data.std(axis=0, ddof=1)

但我无法将其应用于我的数据框的每个“名称”组

所以我想要的结果是:

name, value1, value2
a     -0.5     0.5
a      0.5    -0.5
b     -0.5    -1
b      0.5     1

我尝试了 groupby 和多索引数据框,但可能我没有以正确的方式进行操作

【问题讨论】:

  • 当你说'计算每个“名称”的归一化值'时,你想在每一列内进行归一化(垂直),而不是“在一个组内”=> 跨单个 标准化?

标签: pandas dataframe multi-index normalize


【解决方案1】:

按组归一化是one of the examples in the groupby documentation。但它并没有完全按照您的意愿行事。

In [2]: d.groupby('name').transform(lambda x: (x-x.mean())/x.std(ddof=1))
Out[2]: 
     value1    value2
0 -0.707107  0.707107
1  0.707107 -0.707107
2 -0.707107 -0.707107
3  0.707107  0.707107

您想要的结果表明您实际上希望参考value1value2 中的元素来规范化每个名称组中的值。对于类似的事情,您可以将一个函数单独应用于每个组,然后重新组合结果。

In [3]: def normalize(group):                                                      
    mean = group.values.ravel().mean()
    std = group.values.ravel().std(ddof=1)
    return group.applymap(lambda x: (x - mean)/std)
   ....: 

In [4]: pd.concat([normalize(group) for _, group in d.set_index('name').groupby(level=0)])
Out[4]: 
        value1    value2
name                    
a    -1.224745  1.224745
a     0.000000  0.000000
b    -0.660338 -0.660338
b    -0.132068  1.452744

【讨论】:

  • 显然flatten 复制了数组。 ravel() 工作方式相同,但没有副本。
  • 我不知道那个。谢谢!
  • 谢谢你们!抱歉,由于我的声誉低,我还不能投票!我现在开始对如何使用 pandas 有了更好的认识!
  • OP 希望在 内进行标准化,而不是“在组内”=> 在单个 .
【解决方案2】:

你确定你给出的结果是正确的吗?我假设您想分别标准化 value1 和 value2 。如果这不正确,请告诉我。

#  Easier with `name` as the index.

In [65]: d = d.set_index('name')

In [66]: d
Out[66]: 
      value1  value2
name                
a          1       3
a          2       2
b          4       4
b          5       8

In [68]: means = g.mean()

In [69]: stds = g.std()

In [70]: means
Out[70]: 
      value1  value2
name                
a        1.5     2.5
b        4.5     6.0

In [71]: stds
Out[71]: 
        value1    value2
name                    
a     0.707107  0.707107
b     0.707107  2.828427

In [76]: g.transform(lambda x: (x - means) / stds)
Out[76]: 
        value1    value2
name                    
a    -0.707107  0.707107
a     0.707107 -0.707107
a          NaN       NaN
b          NaN       NaN
b    -0.707107 -0.707107
b     0.707107  0.707107

# Get rid of the nans

In [77]: g.transform(lambda x: (x - means) / stds).dropna()
Out[77]: 
        value1    value2
name                    
a    -0.707107  0.707107
a     0.707107 -0.707107
b    -0.707107 -0.707107
b     0.707107  0.707107

【讨论】:

  • 是的,对不起,您是正确的,我以错误的方式对其进行了标准化!非常感谢,以供将来参考,我想您忘记了 g = d.groupby("name")
猜你喜欢
  • 2018-05-09
  • 2020-08-01
  • 2010-11-11
  • 2020-07-09
  • 2011-07-13
  • 2021-11-13
  • 1970-01-01
  • 2020-07-22
  • 2018-09-13
相关资源
最近更新 更多