熊猫 - 计算所有列的z得分

Sla*_*ron 33 python indexing statistics pandas

我有一个包含单列ID的数据框,所有其他列都是我想要计算z分数的数值.这是它的一个小节:

ID      Age    BMI    Risk Factor
PT 6    48     19.3    4
PT 8    43     20.9    NaN
PT 2    39     18.1    3
PT 9    41     19.5    NaN
Run Code Online (Sandbox Code Playgroud)

我的一些列包含NaN值,我不想将其包括在z-score计算中,所以我打算使用提供给这个问题的解决方案:如何使用nans来规范化pandas列?

df['zscore'] = (df.a - df.a.mean())/df.a.std(ddof=0)
Run Code Online (Sandbox Code Playgroud)

我有兴趣将此解决方案应用于除ID列之外的所有列,以生成新的数据框,我可以将其保存为Excel文件

df2.to_excel("Z-Scores.xlsx")
Run Code Online (Sandbox Code Playgroud)

所以基本上; 如何计算每列的z分数(忽略NaN值)并将所有内容推送到新的数据框中?

SIDENOTE:熊猫中有一个叫做"索引"的概念让我感到恐惧,因为我不太了解它.如果索引是解决此问题的关键部分,请愚蠢地解释索引.

EdC*_*ica 57

从列构建列表并删除您不想计算Z得分的列:

In [66]:
cols = list(df.columns)
cols.remove('ID')
df[cols]

Out[66]:
   Age  BMI  Risk  Factor
0    6   48  19.3       4
1    8   43  20.9     NaN
2    2   39  18.1       3
3    9   41  19.5     NaN
In [68]:
# now iterate over the remaining columns and create a new zscore column
for col in cols:
    col_zscore = col + '_zscore'
    df[col_zscore] = (df[col] - df[col].mean())/df[col].std(ddof=0)
df
Out[68]:
   ID  Age  BMI  Risk  Factor  Age_zscore  BMI_zscore  Risk_zscore  \
0  PT    6   48  19.3       4   -0.093250    1.569614    -0.150946   
1  PT    8   43  20.9     NaN    0.652753    0.074744     1.459148   
2  PT    2   39  18.1       3   -1.585258   -1.121153    -1.358517   
3  PT    9   41  19.5     NaN    1.025755   -0.523205     0.050315   

   Factor_zscore  
0              1  
1            NaN  
2             -1  
3            NaN  
Run Code Online (Sandbox Code Playgroud)

  • @AlexLenail 3年后再次看到这个你可以定义一个`func`并使用`apply`调用这个函数,因为这是`for`循环的语法糖 (2认同)
  • @RyszardCetnarski看到解释https://www.statsdirect.com/help/basics/degrees_freedom.htm和https://stats.stackexchange.com/questions/58230/degrees-of-freedom-for-standard-deviation-of - 例如,它取决于您的用例 (2认同)

Man*_*uel 44

使用Scipy的zscore函数:

df = pd.DataFrame(np.random.randint(100, 200, size=(5, 3)), columns=['A', 'B', 'C'])
df

|    |   A |   B |   C |
|---:|----:|----:|----:|
|  0 | 163 | 163 | 159 |
|  1 | 120 | 153 | 181 |
|  2 | 130 | 199 | 108 |
|  3 | 108 | 188 | 157 |
|  4 | 109 | 171 | 119 |

from scipy.stats import zscore
df.apply(zscore)

|    |         A |         B |         C |
|---:|----------:|----------:|----------:|
|  0 |  1.83447  | -0.708023 |  0.523362 |
|  1 | -0.297482 | -1.30804  |  1.3342   |
|  2 |  0.198321 |  1.45205  | -1.35632  |
|  3 | -0.892446 |  0.792025 |  0.449649 |
|  4 | -0.842866 | -0.228007 | -0.950897 |
Run Code Online (Sandbox Code Playgroud)

如果数据框的所有列都不是数字,则可以使用以下函数将Z-score函数仅应用于数字列select_dtypes:

# Note that `select_dtypes` returns a data frame. We are selecting only the columns
numeric_cols = df.select_dtypes(include=[np.number]).columns
df[numeric_cols].apply(zscore)

|    |         A |         B |         C |
|---:|----------:|----------:|----------:|
|  0 |  1.83447  | -0.708023 |  0.523362 |
|  1 | -0.297482 | -1.30804  |  1.3342   |
|  2 |  0.198321 |  1.45205  | -1.35632  |
|  3 | -0.892446 |  0.792025 |  0.449649 |
|  4 | -0.842866 | -0.228007 | -0.950897 |
Run Code Online (Sandbox Code Playgroud)


Joe*_*elt 9

如果要计算所有列的zscore,可以使用以下命令:

df_zscore = (df - df.mean())/df.std()
Run Code Online (Sandbox Code Playgroud)

  • @pitosalas:@ascripter,你是对的。传递 `df.std(ddof=0)` 产生与 `df.apply(scipy.stats.zscore)` 相同的结果 (3认同)
  • @pitosalas:`std` 函数的默认 `ddof` 可能不同 (2认同)

Sur*_*rya 6

这是使用自定义函数获取 Zscore 的其他方法:

In [6]: import pandas as pd; import numpy as np

In [7]: np.random.seed(0) # Fixes the random seed

In [8]: df = pd.DataFrame(np.random.randn(5,3), columns=["randomA", "randomB","randomC"])

In [9]: df # watch output of dataframe
Out[9]:
    randomA   randomB   randomC
0  1.764052  0.400157  0.978738
1  2.240893  1.867558 -0.977278
2  0.950088 -0.151357 -0.103219
3  0.410599  0.144044  1.454274
4  0.761038  0.121675  0.443863

## Create custom function to compute Zscore 
In [10]: def z_score(df):
   ....:         df.columns = [x + "_zscore" for x in df.columns.tolist()]
   ....:         return ((df - df.mean())/df.std(ddof=0))
   ....:

## make sure you filter or select columns of interest before passing dataframe to function
In [11]: z_score(df) # compute Zscore
Out[11]:
   randomA_zscore  randomB_zscore  randomC_zscore
0        0.798350       -0.106335        0.731041
1        1.505002        1.939828       -1.577295
2       -0.407899       -0.875374       -0.545799
3       -1.207392       -0.463464        1.292230
4       -0.688061       -0.494655        0.099824
Run Code Online (Sandbox Code Playgroud)

使用 scipy.stats zscore 重现的结果

In [12]: from scipy.stats import zscore

In [13]: df.apply(zscore) # (Credit: Manuel)
Out[13]:
    randomA   randomB   randomC
0  0.798350 -0.106335  0.731041
1  1.505002  1.939828 -1.577295
2 -0.407899 -0.875374 -0.545799
3 -1.207392 -0.463464  1.292230
4 -0.688061 -0.494655  0.099824
Run Code Online (Sandbox Code Playgroud)


小智 6

对于 Z 分数,我们可以坚持使用文档而不是使用“应用”功能

from scipy.stats import zscore
df_zscore = zscore(cols as array, axis=1)
Run Code Online (Sandbox Code Playgroud)