我有一个字典,里面有唯一的ID和[分数的样本分布]对,例如:"100":[0.5,0.6,0.2,0.7,0.3]。数组的长度并不完全相同。
对于我字典中的每个项目/"核心"数组,我想在分数分布上拟合一个beta分布,如scipy.stats.beta.fit((,并获得每个样本的alpha/beta参数。然后我想把它放在一本新字典里——所以它会像"101":(1.5,1.8(
我知道我可以通过用for循环迭代我的字典来做到这一点,但字典相当庞大/我想知道是否有更有效的计算方法。
对于上下文,我获取该字典的方式是从pandas数据帧中获取,我在其中这样做:
my_dictionary = df.groupby('unique_id')['score'].apply(list).to_dict()
df看起来像这样:
例如:
df = pd.DataFrame({
'id': ['100', '100', '100', '101', '101', '102'],
'score' : [0.5, 0.3, 0.2, 1, 0.2, 0.9]
})
然后生成的字典看起来像:
{'100': [0.5, 0.3, 0.2], '101': [0.2, 0.1], '102': [0.9]}
是否还有一种方法可以直接从df.groupby级别拟合beta分布,而不必先将其转换为字典,然后用scipy在字典上循环?我能做些什么吗:
df.groupby('unique_id')['score'].apply(stats.beta.fit()).to_dict()
或者类似的东西?
试试这个:
df=df.groupby('id').apply(lambda x: list(beta.fit(x.score)))
dc=df.to_dict()
输出:
df
id
100 [0.2626434905176847, 0.37866242902872393, 0.18...
101 [1.253982875508286, 0.8832540117966552, -0.093...
102 [1.044551187075241, 1.0167687597781938, 0.8999...
dtype: object
dc
{'100': [0.2626434905176847, 0.37866242902872393, 0.18487097639113187, 0.3151290236088682],
'101': [1.253982875508286, 0.8832540117966552, -0.09383386122371801, 1.0938338612237182],
'102': [1.044551187075241, 1.0167687597781938, 0.8999999999999999, 1.1272504901983386e-16]}
正如我所认识到的,每行数据帧df
:需要适应多个贝塔系数
df['beta_fit'] = df['score'].apply( lambda x: stats.beta.fit(x))
现在结果存储在df['beta_fit']
:中
0 (0.5158954356434775, 0.4824876600627905, 0.154...
1 (0.18219650169013427, 0.18228236200252418, 0.1...
2 (2.874609362944296, 0.8497751096020354, -0.341...
3 (1.313976940871222, 0.5956397575363881, -0.093...
Name: beta_fit, dtype: object
如果要保持位置(loc
(和比例(scale
(固定,则需要在scipy.stats.beta.fit
中指出这一点。您可以使用functools.partial
进行以下操作:
import pandas as pd
>>> import scipy.stats
>>> from functools import partial
>>> df = pd.DataFrame({
... 'id': ['100', '100', '100', '101', '101', '102'],
... 'score' : [0.5, 0.3, 0.2, 0.1, 0.2, 0.9]
... })
>>> beta = partial(scipy.stats.beta.fit, floc=0, fscale=1)
>>> df.groupby('id')['score'].apply(beta)
id
100 (4.82261025047374, 9.616623800842953, 0, 1)
101 (0.7079910251948778, 0.910200073771759, 0, 1)
Name: score, dtype: object
请注意,我已经调整了您的输入示例,因为它包含不正确的值(1.0(,而且在某些情况下,值太少,无法成功拟合。