按组对变量进行标准化 - 为什么均值始终为零?
Standardize variable by group - why is the mean always zero?
我有以下数据:
df = pd.DataFrame({'sound': ['A', 'B', 'B', 'A', 'B', 'A'],
'score': [10, 5, 6, 7, 11, 1]})
print(df)
sound score
0 A 10
1 B 5
2 B 6
3 A 7
4 B 11
5 A 1
如果我标准化(即 Z 分数)score
变量,我会得到以下值。新的z
列的均值基本为0,SD为1,两者都是标准化变量的预期:
df['z'] = (df['score'] - df['score'].mean())/df['score'].std()
print(df)
print('Mean: {}'.format(df['z'].mean()))
print('SD: {}'.format(df['z'].std()))
sound score z
0 A 10 0.922139
1 B 5 -0.461069
2 B 6 -0.184428
3 A 7 0.092214
4 B 11 1.198781
5 A 1 -1.567636
Mean: -7.401486830834377e-17
SD: 1.0
但是,我真正感兴趣的是根据组成员身份计算 Z 分数 (sound
)。例如,如果分数来自声音 A,则仅使用 声音 A 值 的平均值和标准差将该值转换为 Z 分数。同样,声音 B 的 Z 分数将仅使用声音 B 的平均值和 SD。与常规 Z 分数计算相比,这显然会产生不同的值:
df['zg'] = df.groupby('sound')['score'].transform(lambda x: (x - x.mean()) / x.std())
print(df)
print('Mean: {}'.format(df['zg'].mean()))
print('SD: {}'.format(df['zg'].std()))
sound score z zg
0 A 10 0.922139 0.872872
1 B 5 -0.461069 -0.725866
2 B 6 -0.184428 -0.414781
3 A 7 0.092214 0.218218
4 B 11 1.198781 1.140647
5 A 1 -1.567636 -1.091089
Mean: 3.700743415417188e-17
SD: 0.894427190999916
我的问题是:为什么基于组的标准化值(zg
)的均值也基本等于0?这是预期的行为还是我的计算某处有错误?
z
分数是有意义的,因为在变量内进行标准化实质上会将平均值强制为 0。但是 zg
值是使用每个声音组的不同平均值和 SD 计算的,所以我不确定为什么新变量的均值也设置为 0。
我唯一能看到这种情况发生的情况是,如果值之和 > 0 等于值之和 < 0,当取平均值时会抵消为 0。这发生在常规 Z 分数计算中,但我很惊讶在像这样跨多个组操作时也会发生这种情况...
我认为这很有道理。如果 E[abc
| def
] 是 abc
给定 def
) 的期望,然后在 df['zg']
:
m1
= E['zg'
| sound = 'A'
] = (0.872872 + 0.218218 -1.091089)/3
~ 0
m2
= E['zg'
| sound = 'B'
] = (-0.725866 - 0.414781 + 1.140647)/3
~ 0
和
E['zg'
] = (m1+m2)/2
= (0.872872 + 0.218218 -1.091089 -0.725866 - 0.414781 + 1.140647)/6
~ 0
是的,这是预期的行为。
换句话说,使用 Law of Iterated Expectations、
具体来说,如果群 Y
是有限的,因此是可数的,
哪里
但是,根据构造,每个 E[X|Y_j]
是 0
对于您的集合 G
中的所有 Y
值。
因此,总平均值也将为零。
我有以下数据:
df = pd.DataFrame({'sound': ['A', 'B', 'B', 'A', 'B', 'A'],
'score': [10, 5, 6, 7, 11, 1]})
print(df)
sound score
0 A 10
1 B 5
2 B 6
3 A 7
4 B 11
5 A 1
如果我标准化(即 Z 分数)score
变量,我会得到以下值。新的z
列的均值基本为0,SD为1,两者都是标准化变量的预期:
df['z'] = (df['score'] - df['score'].mean())/df['score'].std()
print(df)
print('Mean: {}'.format(df['z'].mean()))
print('SD: {}'.format(df['z'].std()))
sound score z
0 A 10 0.922139
1 B 5 -0.461069
2 B 6 -0.184428
3 A 7 0.092214
4 B 11 1.198781
5 A 1 -1.567636
Mean: -7.401486830834377e-17
SD: 1.0
但是,我真正感兴趣的是根据组成员身份计算 Z 分数 (sound
)。例如,如果分数来自声音 A,则仅使用 声音 A 值 的平均值和标准差将该值转换为 Z 分数。同样,声音 B 的 Z 分数将仅使用声音 B 的平均值和 SD。与常规 Z 分数计算相比,这显然会产生不同的值:
df['zg'] = df.groupby('sound')['score'].transform(lambda x: (x - x.mean()) / x.std())
print(df)
print('Mean: {}'.format(df['zg'].mean()))
print('SD: {}'.format(df['zg'].std()))
sound score z zg
0 A 10 0.922139 0.872872
1 B 5 -0.461069 -0.725866
2 B 6 -0.184428 -0.414781
3 A 7 0.092214 0.218218
4 B 11 1.198781 1.140647
5 A 1 -1.567636 -1.091089
Mean: 3.700743415417188e-17
SD: 0.894427190999916
我的问题是:为什么基于组的标准化值(zg
)的均值也基本等于0?这是预期的行为还是我的计算某处有错误?
z
分数是有意义的,因为在变量内进行标准化实质上会将平均值强制为 0。但是 zg
值是使用每个声音组的不同平均值和 SD 计算的,所以我不确定为什么新变量的均值也设置为 0。
我唯一能看到这种情况发生的情况是,如果值之和 > 0 等于值之和 < 0,当取平均值时会抵消为 0。这发生在常规 Z 分数计算中,但我很惊讶在像这样跨多个组操作时也会发生这种情况...
我认为这很有道理。如果 E[abc
| def
] 是 abc
给定 def
) 的期望,然后在 df['zg']
:
m1
= E['zg'
| sound = 'A'
] = (0.872872 + 0.218218 -1.091089)/3
~ 0
m2
= E['zg'
| sound = 'B'
] = (-0.725866 - 0.414781 + 1.140647)/3
~ 0
和
E['zg'
] = (m1+m2)/2
= (0.872872 + 0.218218 -1.091089 -0.725866 - 0.414781 + 1.140647)/6
~ 0
是的,这是预期的行为。
换句话说,使用 Law of Iterated Expectations、
具体来说,如果群 Y
是有限的,因此是可数的,
哪里
但是,根据构造,每个 E[X|Y_j]
是 0
对于您的集合 G
中的所有 Y
值。
因此,总平均值也将为零。