如何规范化多索引数据框?
假设我有数据框:
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和一个多索引数据框,但可能我没有以正确的方式做到这一点
答案 0 :(得分:7)
按组进行规范化是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
您想要的结果表明您实际上想要参考value1
和value2
中的元素来规范化每个名称组中的值。对于类似的东西,你可以单独为每个组应用一个函数,然后重新组合结果。
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
答案 1 :(得分:0)
你确定你给出的结果是正确的吗?我假设你想分别规范化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