当均值和标准差值依赖于另一列值时,对特定列的所有值应用高斯分布

时间:2018-09-05 16:40:56

标签: python pandas group-by gaussian normal-distribution

有什么方法可以创建一个新列,其中包含每个列值的高斯/正态分布以及彼此不同的列值?

我的意思是,如果我有两个具有以下结构的数据框:

>> Original Dataframe 1

      Samp     Age     Cs
1       A      51      msi
2       B      62      cin
3       C      55      msi
4       D      70      ebv
5       E      56      gs
....



>> Original DataFrame 2

   Samp   Cs  Age 
0     A  cin   51 
1     A  ebv   51
2     A   gs   51
3     A  msi   51
4     B  cin   62
5     B  ebv   62
6     B   gs   62
7     B  msi   62
8     C  cin   55
9     C  ebv   55
10    C   gs   55
11    C  msi   55
12    D  cin   70
13    D  ebv   70
14    D   gs   70
15    D  msi   70
16    E  cin   56
17    E  ebv   56
18    E   gs   56
19    E  msi   56
...

如您所见,原始数据框2 原始数据框1 CS 列的唯一值的重复行。

要实现我的目标,我需要从原始数据框1 中检索所有唯一的 Cs 值的均值和标准差,因此我可以将其进一步应用于年龄年龄列中的>“原始数据框2” ,以获取新的数据-所需Datframe ,并添加新列概率

由于在这种情况下,原始DataFrame 1 的均值和标准差是

m = {'msi': 70.7, 'ebv': 63.2, 'cin': 66.9, 'gs': 59.3}
std = {'msi': 8.7, 'ebv': 11.2, 'cin': 10.2, 'gs': 10.2}

有什么方法可以输出以下数据帧?

    >> Desired DataFrame

   Samp   Cs  Age  Probability
0     A  cin   51   0.01160
1     A  ebv   51   0.01968
2     A   gs   51   0.02809
3     A  msi   51   0.00353
4     B  cin   62   0.03485
5     B  ebv   62   0.03542
6     B   gs   62   0.03777
7     B  msi   62   0.00455
8     C  cin   55   0.01980
9     C  ebv   55   0.02725
10    C   gs   55   0.03579
11    C  msi   55   0.00900
12    D  cin   70   0.03735
13    D  ebv   70   0.02963
14    D   gs   70   0.02256
15    D  msi   70   0.04570
16    E  cin   56   0.02210
17    E  ebv   56   0.02897
18    E   gs   56   0.03712
19    E  msi   56   0.01100
...

到目前为止,这是我的尝试:

def get_age_cs_probs(df):
    df['Probability'] = df.groupby('Cs').Age.apply(lambda x: 
                                                         (1/(np.sqrt(2*3.14*(x.std()**2))))*(np.exp(-(((x-x.mean())**2)/(2*(x.std()**2))))))
    return df

1 个答案:

答案 0 :(得分:0)

scipy.stats.zmap将基于不同的数组为您的数组提供z分数。

此结果可以反馈到scipy.stats.norm.cdf(),它将把您的z得分转换为概率。

查看这两个函数以查看是否要指定不同于默认值的df或其他值。

我有一个答案,可以为每个“ Cs”值生成一个概率列表,但还不太清楚将其重新放入df2的方法。

df1
Out[117]: 
  Samp  Age   Cs
1    A   51  msi
2    B   62  cin
3    C   55  msi
4    D   70  ebv
5    E   56   gs

df2
Out[118]: 
   Samp   Cs  Age  Probability
0     A  cin   51      0.01160
1     A  ebv   51      0.01968
2     A   gs   51      0.02809
3     A  msi   51      0.00353
4     B  cin   62      0.03485
5     B  ebv   62      0.03542
6     B   gs   62      0.03777
7     B  msi   62      0.00455
8     C  cin   55      0.01980
9     C  ebv   55      0.02725
10    C   gs   55      0.03579
11    C  msi   55      0.00900
12    D  cin   70      0.03735
13    D  ebv   70      0.02963
14    D   gs   70      0.02256
15    D  msi   70      0.04570
16    E  cin   56      0.02210
17    E  ebv   56      0.02897
18    E   gs   56      0.03712
19    E  msi   56      0.01100

[st.norm.cdf(st.zmap(df2[df2.loc[:, 'Cs'] == x].Age, df1[df1.loc[:, 'Cs']==x].Age)) for x in df2.Cs.unique()]

Out[119]: 
[array([ 0., nan,  0.,  1.,  0.]),
 array([ 0.,  0.,  0., nan,  0.]),
 array([ 0.,  1.,  0.,  1., nan]),
 array([0.15865525, 0.9999966 , 0.84134475, 1.        , 0.9331928 ])]

这与您的预期输出不完全匹配,但是如果您的df1具有您在问题中列出的属性(即,相同的m和sd值),则将与之匹配。