生成汇总为1的值列表-在groupby中?

时间:2019-11-14 19:32:00

标签: pandas numpy dataframe

根据几年前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的解决方案,但是我认为遵循这些原则是可以的。

有什么想法吗?有什么建议吗?解决方案?

1 个答案:

答案 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