Python 按两列分组,并使用列中的两个不同数据子集计算百分比

Python 按两列分组,并使用列中的两个不同数据子集计算百分比,python,pandas,dataframe,Python,Pandas,Dataframe,我正在寻找解决方案,但一直被卡住 我有一个dataframe,它包含四列ID组类型值。我想按组、值对记录进行分组,并根据类型列中的值计算百分比。此列numer,denom中只能存在两个值 我的数据如下所示: df = pd.DataFrame({'ID': ['A', 'A', 'B', 'B', 'C', 'C', 'D', 'D', 'D', 'D', 'E'], 'group': ['red', 'red', 'red', 'red', 'green'

我正在寻找解决方案,但一直被卡住

我有一个dataframe,它包含四列ID组类型值。我想按组、值对记录进行分组,并根据类型列中的值计算百分比。此列numer,denom中只能存在两个值

我的数据如下所示:

df = pd.DataFrame({'ID': ['A', 'A', 'B', 'B', 'C', 'C', 'D', 'D', 'D', 'D', 'E'],
                   'group': ['red', 'red', 'red', 'red', 'green', 'green', 'blue', 'blue', 'blue', 'blue', 'blue'],
                   'type': ['numer', 'denom', 'numer', 'denom', 'numer', 'denom', 'numer', 'denom', 'numer', 'denom',
                            'denom'],
                   'value': ['1', '1', '0', 'NaN', '2', '2', '1', '1', '2', '2', '2']
                   })
# df
   ID  group   type value
0   A    red  numer     1
1   A    red  denom     1
2   B    red  numer     0
3   B    red  denom   NaN
4   C  green  numer     2
5   C  green  denom     2
6   D   blue  numer     1
7   D   blue  denom     1
8   D   blue  numer     2
9   D   blue  denom     2
10  E   blue  denom     2
group  value  percent
red        0      0.0
           1      1.0
           2      0.0
         NaN      0.0
green      0      0.0
           1      0.0
           2      1.0
         NaN      0.0     
blue       0      0.0
           1      1.0
           2      0.5
         NaN      0.0
我想将numer的计数除以每个分组对组的denom的计数,因此最终结果如下所示:

df = pd.DataFrame({'ID': ['A', 'A', 'B', 'B', 'C', 'C', 'D', 'D', 'D', 'D', 'E'],
                   'group': ['red', 'red', 'red', 'red', 'green', 'green', 'blue', 'blue', 'blue', 'blue', 'blue'],
                   'type': ['numer', 'denom', 'numer', 'denom', 'numer', 'denom', 'numer', 'denom', 'numer', 'denom',
                            'denom'],
                   'value': ['1', '1', '0', 'NaN', '2', '2', '1', '1', '2', '2', '2']
                   })
# df
   ID  group   type value
0   A    red  numer     1
1   A    red  denom     1
2   B    red  numer     0
3   B    red  denom   NaN
4   C  green  numer     2
5   C  green  denom     2
6   D   blue  numer     1
7   D   blue  denom     1
8   D   blue  numer     2
9   D   blue  denom     2
10  E   blue  denom     2
group  value  percent
red        0      0.0
           1      1.0
           2      0.0
         NaN      0.0
green      0      0.0
           1      0.0
           2      1.0
         NaN      0.0     
blue       0      0.0
           1      1.0
           2      0.5
         NaN      0.0
到目前为止,我一直在尝试将类似的方法应用于此,就像在使用窗口函数的SQL中一样。我当前的代码没有使用counts of numer/counts of denom计算我想要的值。相反,它根据每个分组对中的小计计算百分比:

res = df.groupby(['group','value']).agg({'ID': 'count'})
pct_df = res.groupby(level=0).apply(lambda x: 100 * x / float(x.sum()))

#pct_df
               ID
group value      
blue  1      0.40
      2      0.60
green 2      1.00
red   0      0.25
      1      0.50
      NaN    0.25
您可以在groupby之后使用apply,然后重新索引多索引以生成所需的索引

你也可以试试

def分区编号,名称: 如果denom else为0,则返回numer/denom res=df.groupby['group','value']['type'].applylambda col:divisionsumcol.eq'numer',sumcol.eq'denom'。到_frame'percent' index=pd.MultiIndex.from_产品[df['group'].unique,sorteddf['value'].unique],name=res.index.names res=res.reindexindex,填充值=0 您可以使用pandas.pivot\u表

或者,pandas.groupby with.applylambda x:x.value\u counts.to\u dict.get,np.nan。这基本上将值_counts结果转换为dictionary,并使用dictionary上的.get方法检索值或np。如果字典里不存在的话

df.groupby(['group','value'])['type'].apply(lambda x: x.value_counts().to_dict().get('numer', np.nan) / x.value_counts().to_dict().get('denom', np.nan))
df.groupby(['group','value'])['type'].apply(lambda x: x.value_counts().to_dict().get('numer', np.nan) / x.value_counts().to_dict().get('denom', np.nan))
group  value
blue   1        1.0
       2        0.5
green  2        1.0
red    0        NaN
       1        1.0
       NaN      NaN
Name: type, dtype: float64