根据几年前Generating a list of random numbers, summing to 1的精神,是否有办法将np.random.dirichlet结果的np数组结果应用于数据帧的groupby?
例如,我可以遍历letter列的唯一值并一次应用一个:
df = pd.DataFrame([['a', 1], ['a', 3], ['a', 2], ['a', 6],
['b', 7],['b', 5],['b', 4],], columns=['letter', 'value'])
df['grp_sum'] = df.groupby('letter')['value'].transform('sum')
df['prop_of_total'] = np.random.dirichlet(np.ones(len(df)), size=1).tolist()[0]
for letter in df['letter'].unique():
sz=len(df[df['letter'] == letter])
df.loc[df['letter'] == letter, 'prop_of_grp'] = np.random.dirichlet(np.ones(sz), size=1).tolist()[0]
print(df)
导致:
letter value grp_sum prop_of_total prop_of_grp
0 a 1 12 0.015493 0.293481
1 a 3 12 0.114027 0.043973
2 a 2 12 0.309150 0.160818
3 a 6 12 0.033999 0.501729
4 b 7 16 0.365276 0.617484
5 b 5 16 0.144502 0.318075
6 b 4 16 0.017552 0.064442
,但是有一种比迭代唯一值并过滤每个值的更好的方法。这个很小,但是我可能会有成千上万个分组,每个分组的大小大约为50-100行,并且每个分组都需要不同的随机分布。
我还考虑过为每个分组创建一个临时数据框,附加到第二个数据框并最终合并结果,尽管看上去比这更令人费解。我还没有找到可以将groupby大小的数组应用于groupby的解决方案,但是我认为遵循这些原则是可以的。
有什么想法吗?有什么建议吗?解决方案?
答案 0 :(得分:0)
IIUC,执行transform()
:
def direchlet(x, size=1):
return np.array(np.random.dirichlet(np.ones(len(x)), size=size)[0])
df['prop_of_grp'] = df.groupby('letter')['value'].transform(direchlet)
输出:
letter value grp_sum prop_of_total prop_of_grp
0 a 1 12 0.102780 0.127119
1 a 3 12 0.079201 0.219648
2 a 2 12 0.341158 0.020776
3 a 6 12 0.096956 0.632456
4 b 7 16 0.193970 0.269094
5 b 5 16 0.012905 0.516035
6 b 4 16 0.173031 0.214871