如何在数据框的每一列上计算修改后的 Z 分数和 IQR
How to calculate modified Z score and IQR on each column of the dataframe
我有一个数据框,我正在尝试在分析之前清理数据。
由于我的数据有点复杂,我正在放一个样本数据进行试用。
A B C D
30 24 13 41
30 25 14 45
30 27 15 44
30 28 16 43
31 21 12 4
31 2 17 99
3 89 99 45
78 24 0 43
35 252 12 45
36 23 13 44
我正在尝试处理异常值并尝试计算修改后的 Z 分数(中位数)和 IQR 以从数据中过滤掉异常值,以便我可以获得用于进一步分析的质量数据。
我想计算 IQR,然后计算每一列的 Z 分数,并过滤掉数据框中每一列的异常值。
到目前为止我已经尝试了一些东西,比如:
IQR:
for col in df2.columns:
col = np.array([col])
q1_a = np.percentile(col, 25)
q3_a = np.percentile(col, 75)
iqr1 = q3_a - q1_a
print(iqr1)
修改后的 Z 分数:
for col in df2.columns:
threshold = 3.5
col_zscore = col +'_zscore'
median_y = df[col].median()
print(median_y)
median_absolute_deviation_y = (np.abs(df2[col] - median_y)).median()
print(median_absolute_deviation_y)
modified_z_scores = 0.7413 *((df2[col] - median_y)/median_absolute_deviation_y)
print(modified_z_scores)
df2[col_zscore] = np.abs(modified_z_scores)
df2 = df2[(np.abs(df2[col_zscore]) < 3.5).all(axis=1)]
print(df2)
但没有得到正确答案。该功能不适用于每一列,并在最后创建我想要的数据框。
请帮忙。
谢谢
对于IQR问题:
Weight Age
0 40 20
1 62 21
2 35 19
3 29 18
如果你的数据框是这样的,你可以使用下面的代码计算 IQR。
for col in df2.columns:
col_values = df2[col]
col_values = np.array([col_values])
q1_a = np.percentile(col_values, 25)
q3_a = np.percentile(col_values, 75)
iqr1 = q3_a - q1_a
print(iqr1)
如果所有数据列都包含数值数据,则可以使用上述代码计算IQR,否则需要先将分类数据列编码为数值。如果您需要特定的 IQR 值,请查看 numpy percentile interpolation 参数。
对于Z_score问题:
df3 = df2
for col in df2.columns:
threshold = 3.5
col_zscore = col +'_zscore'
median_y = df2[col].median()
print(median_y)
median_absolute_deviation_y = (np.abs(df2[col]-median_y)).median()
print(median_absolute_deviation_y)
modified_z_scores = 0.7413 *((df2[col] - median_y)/median_absolute_deviation_y)
print(modified_z_scores)
df2[col_zscore] = np.abs(modified_z_scores)
df2 = df3[(np.abs(df3[col_zscore]) < 3.5)]
print(df2)
试试上面的代码。
使用scipy
:
数据:
A B C D
30 24 13 41
30 25 14 45
30 27 15 44
30 28 16 43
31 21 12 4
31 2 17 99
3 89 99 45
78 24 0 43
35 252 12 45
36 23 13 44
代码:
pandas.DataFrame.apply
可用于进行列 (axis=0
) 或行 (axis=1
) 明智的计算。
import pandas as pd
import scipy
df.apply(scipy.stats.iqr)
# output
A 4.0
B 4.5
C 3.5
D 2.0
dtype: float64
df.apply(scipy.stats.zscore)
# output
A B C D
-0.196943 -0.392191 -0.307452 -0.200009
-0.196943 -0.377930 -0.269495 -0.013954
-0.196943 -0.349407 -0.231538 -0.060468
-0.196943 -0.335145 -0.193581 -0.106981
-0.139019 -0.434976 -0.345409 -1.921013
-0.139019 -0.705944 -0.155624 2.497782
-1.760907 0.534806 2.956852 -0.013954
2.583435 -0.392191 -0.800893 -0.106981
0.092679 2.859432 -0.345409 -0.013954
0.150604 -0.406453 -0.307452 -0.060468
验证 iqr:
df.describe()
- 目视检查
df.describe()
输出,很容易确认 scipy.stats.iqr
的结果
df.describe().loc[['25%', '75%']]
# Output
A B C D
25% 30.0 23.25 12.25 43.0
75% 34.0 27.75 15.75 45.0
df
变换(修改后的 z 分数):
- 一个z-score是偏离均值的标准差的个数,一个数据点是。从技术上讲,它衡量的是低于或高于总体平均值的标准差有多少,即原始分数。 Z分数也称为标准分数,可以放在正态分布曲线上。
import numpy as np
def mod_z(col: pd.Series, thresh: float=3.5) -> pd.Series:
med_col = col.median()
med_abs_dev = (np.abs(col - med_col)).median()
mod_z = 0.7413 * ((col - med_col) / med_abs_dev)
mod_z = mod_z[np.abs(mod_z) < thresh]
return np.abs(mod_z)
df_mod_z = df.apply(mod_z)
# Output
A B C D
0.7413 0.12355 0.2471 2.2239
0.7413 0.12355 0.2471 0.7413
0.7413 0.61775 0.7413 0.0000
0.7413 0.86485 1.2355 0.7413
0.7413 0.86485 0.7413 NaN
0.7413 NaN 1.7297 NaN
NaN NaN NaN 0.7413
NaN 0.12355 NaN 0.7413
NaN NaN 0.7413 0.7413
NaN 0.37065 0.2471 0.0000
过滤后的原始数据帧:
df_filtered = df[df_mod_z >= 0]
print(df_filtered)
输出
A B C D
30.0 24.0 13.0 41.0
30.0 25.0 14.0 45.0
30.0 27.0 15.0 44.0
30.0 28.0 16.0 43.0
31.0 21.0 12.0 NaN
31.0 NaN 17.0 NaN
NaN NaN NaN 45.0
NaN 24.0 NaN 43.0
NaN NaN 12.0 45.0
NaN 23.0 13.0 44.0
我有一个数据框,我正在尝试在分析之前清理数据。
由于我的数据有点复杂,我正在放一个样本数据进行试用。
A B C D
30 24 13 41
30 25 14 45
30 27 15 44
30 28 16 43
31 21 12 4
31 2 17 99
3 89 99 45
78 24 0 43
35 252 12 45
36 23 13 44
我正在尝试处理异常值并尝试计算修改后的 Z 分数(中位数)和 IQR 以从数据中过滤掉异常值,以便我可以获得用于进一步分析的质量数据。
我想计算 IQR,然后计算每一列的 Z 分数,并过滤掉数据框中每一列的异常值。
到目前为止我已经尝试了一些东西,比如:
IQR:
for col in df2.columns:
col = np.array([col])
q1_a = np.percentile(col, 25)
q3_a = np.percentile(col, 75)
iqr1 = q3_a - q1_a
print(iqr1)
修改后的 Z 分数:
for col in df2.columns:
threshold = 3.5
col_zscore = col +'_zscore'
median_y = df[col].median()
print(median_y)
median_absolute_deviation_y = (np.abs(df2[col] - median_y)).median()
print(median_absolute_deviation_y)
modified_z_scores = 0.7413 *((df2[col] - median_y)/median_absolute_deviation_y)
print(modified_z_scores)
df2[col_zscore] = np.abs(modified_z_scores)
df2 = df2[(np.abs(df2[col_zscore]) < 3.5).all(axis=1)]
print(df2)
但没有得到正确答案。该功能不适用于每一列,并在最后创建我想要的数据框。 请帮忙。 谢谢
对于IQR问题:
Weight Age
0 40 20
1 62 21
2 35 19
3 29 18
如果你的数据框是这样的,你可以使用下面的代码计算 IQR。
for col in df2.columns:
col_values = df2[col]
col_values = np.array([col_values])
q1_a = np.percentile(col_values, 25)
q3_a = np.percentile(col_values, 75)
iqr1 = q3_a - q1_a
print(iqr1)
如果所有数据列都包含数值数据,则可以使用上述代码计算IQR,否则需要先将分类数据列编码为数值。如果您需要特定的 IQR 值,请查看 numpy percentile interpolation 参数。
对于Z_score问题:
df3 = df2
for col in df2.columns:
threshold = 3.5
col_zscore = col +'_zscore'
median_y = df2[col].median()
print(median_y)
median_absolute_deviation_y = (np.abs(df2[col]-median_y)).median()
print(median_absolute_deviation_y)
modified_z_scores = 0.7413 *((df2[col] - median_y)/median_absolute_deviation_y)
print(modified_z_scores)
df2[col_zscore] = np.abs(modified_z_scores)
df2 = df3[(np.abs(df3[col_zscore]) < 3.5)]
print(df2)
试试上面的代码。
使用scipy
:
数据:
A B C D
30 24 13 41
30 25 14 45
30 27 15 44
30 28 16 43
31 21 12 4
31 2 17 99
3 89 99 45
78 24 0 43
35 252 12 45
36 23 13 44
代码:
pandas.DataFrame.apply
可用于进行列 (axis=0
) 或行 (axis=1
) 明智的计算。
import pandas as pd
import scipy
df.apply(scipy.stats.iqr)
# output
A 4.0
B 4.5
C 3.5
D 2.0
dtype: float64
df.apply(scipy.stats.zscore)
# output
A B C D
-0.196943 -0.392191 -0.307452 -0.200009
-0.196943 -0.377930 -0.269495 -0.013954
-0.196943 -0.349407 -0.231538 -0.060468
-0.196943 -0.335145 -0.193581 -0.106981
-0.139019 -0.434976 -0.345409 -1.921013
-0.139019 -0.705944 -0.155624 2.497782
-1.760907 0.534806 2.956852 -0.013954
2.583435 -0.392191 -0.800893 -0.106981
0.092679 2.859432 -0.345409 -0.013954
0.150604 -0.406453 -0.307452 -0.060468
验证 iqr:
df.describe()
- 目视检查
df.describe()
输出,很容易确认scipy.stats.iqr
的结果
df.describe().loc[['25%', '75%']]
# Output
A B C D
25% 30.0 23.25 12.25 43.0
75% 34.0 27.75 15.75 45.0
df
变换(修改后的 z 分数):
- 一个z-score是偏离均值的标准差的个数,一个数据点是。从技术上讲,它衡量的是低于或高于总体平均值的标准差有多少,即原始分数。 Z分数也称为标准分数,可以放在正态分布曲线上。
import numpy as np
def mod_z(col: pd.Series, thresh: float=3.5) -> pd.Series:
med_col = col.median()
med_abs_dev = (np.abs(col - med_col)).median()
mod_z = 0.7413 * ((col - med_col) / med_abs_dev)
mod_z = mod_z[np.abs(mod_z) < thresh]
return np.abs(mod_z)
df_mod_z = df.apply(mod_z)
# Output
A B C D
0.7413 0.12355 0.2471 2.2239
0.7413 0.12355 0.2471 0.7413
0.7413 0.61775 0.7413 0.0000
0.7413 0.86485 1.2355 0.7413
0.7413 0.86485 0.7413 NaN
0.7413 NaN 1.7297 NaN
NaN NaN NaN 0.7413
NaN 0.12355 NaN 0.7413
NaN NaN 0.7413 0.7413
NaN 0.37065 0.2471 0.0000
过滤后的原始数据帧:
df_filtered = df[df_mod_z >= 0]
print(df_filtered)
输出
A B C D
30.0 24.0 13.0 41.0
30.0 25.0 14.0 45.0
30.0 27.0 15.0 44.0
30.0 28.0 16.0 43.0
31.0 21.0 12.0 NaN
31.0 NaN 17.0 NaN
NaN NaN NaN 45.0
NaN 24.0 NaN 43.0
NaN NaN 12.0 45.0
NaN 23.0 13.0 44.0