熊猫在组内获得价值分布

时间:2019-02-12 16:01:13

标签: python pandas

我有一个简单的数据框,例如:

  cens codf  codid
0  S01  F01      1
1  S01  F01      2
2  S01  F02      3
3  S01  F03      4
4  S02  F04      5
5  S02  F05      6

我试图根据每个组中cens个计数的分布从每个codf组中选择一个随机样本。基本上,如果我分组:

In [387]: df.groupby('cens')['codf'].value_counts()                                                                                                               
Out[387]: 
cens  codf
S01   F01     2
      F02     1
      F03     1
S02   F04     1
      F05     1
Name: codf, dtype: int64

在S01 cens组中,codf应该具有(如矢量)(非归一化)概率分布:

[0,33 0,66 0,66]

这意味着1的a具有值为2的codf和2的值为值1的2 codf的两倍。我想得到一个样本,假设每个组中有50%的行根据以前的分布。

我知道我可以做到

df.groupby('cens').apply(lambda x: x.sample(frac=0.5))

但是这里的问题是在weight函数的sample关键字中添加前一个向量。我试图将其添加到原始数据框中,但到目前为止,我只能添加一个具有相对出现次数的列。具有列分布(非规范化)的数据框应显示为:

  cens codf  codid pdf
0  S01  F01      1 0.33
1  S01  F01      2 0.33
2  S01  F02      3 0.66
3  S01  F03      4 0.66
4  S02  F04      5 1.00
5  S02  F05      6 1.00

然后我应该能够写:

df.groupby('cens').apply(lambda x: x.sample(frac=0.5, weight=df['pdf']))

1 个答案:

答案 0 :(得分:1)

我没有使用value_count,因为您要将值分配回原始df,所以我正在使用transform

s=df.groupby(['cens','codf']).codf.transform('count')
s1=df['codf'].groupby([df['cens'],s]).transform('nunique')
s1
Out[256]: 
0    1
1    1
2    2
3    2
4    2
5    2
Name: codf, dtype: int64
df['pdf']=s1/df.groupby(['cens']).codf.transform('nunique')
df
Out[258]: 
  cens codf  codid       pdf
0  S01  F01      1  0.333333
1  S01  F01      2  0.333333
2  S01  F02      3  0.666667
3  S01  F03      4  0.666667
4  S02  F04      5  1.000000
5  S02  F05      6  1.000000