Python 数据帧分组按多级选择

Python 数据帧分组按多级选择,python,python-3.x,pandas,Python,Python 3.x,Pandas,我正试图用pandas来解决我用纯python解决的问题,但不知道DataFrameGroupBy的最佳实践 我想为每个邮政编码选择最多处方药物的百分比(占该邮政编码中所有药物的百分比)。 如果两种药物的处方量相同,我想选择“按字母顺序第一”的药物: 我已经按邮政编码进行了分组,但在选择行时遇到了问题(应用lambda) 所有按邮政编码销售的药品,我打算将此药品与之前的数据集一起使用: all_by_post_code = drugs_prescriptions.groupby(['PostC

我正试图用pandas来解决我用纯python解决的问题,但不知道DataFrameGroupBy的最佳实践

我想为每个邮政编码选择最多处方药物的百分比(占该邮政编码中所有药物的百分比)。 如果两种药物的处方量相同,我想选择“按字母顺序第一”的药物:

我已经按邮政编码进行了分组,但在选择行时遇到了问题(应用lambda)

所有按邮政编码销售的药品,我打算将此药品与之前的数据集一起使用:

all_by_post_code = drugs_prescriptions.groupby(['PostCode'])['Quantity'].sum()

我不知道如何选择每个邮政编码中药品最大数量的行,如果两种药品的数量相同,则应选择第一个字母顺序的药品(D1表示邮政编码P2)

我一直想做这样的事情:

durg_qualtity_per_post_code [durg_qualtity_per_post_code .apply(lambda x: int(x['Quantity']) == max_items_by_post_code[x['post_code']], axis=1, reduce=True)]
更新:

# sort by PostCode, Drug
df = drugs_prescriptions.groupby(['PostCode', 'Drug']).agg('sum')
df = df.groupby(['PostCode']).apply(lambda x: x.sort_values(['Quantity', 'Drug'], ascending=[False, True]))

# select first value by PostCode
# reset index in order to have drug in the output as well
df.reset_index(level=[1], inplace=True)
df = df.groupby(['PostCode']).first()

# calculate percentage of total by PostCode
allQuantities = drugs_prescriptions.groupby(['PostCode']).agg('sum')
df['Quantity'] = df.apply(lambda row: row['Quantity']/allQuantities.loc[row.name], axis=1)

这里有一个可能的解决方案,但它让人觉得很尴尬,也不符合python。但它是有效的,注释在代码中

# setting string to integer
df.Quantity = df.Quantity.astype('int')

# create a mulitiindex
df.set_index(['PostCode', 'Drug'], inplace=True)

# use transform to divide the sum of the 'Drug' level by the 'PostCode' level
df = df.groupby(level=[0,1]).transform('sum') / df.groupby(level=0).transform('sum')

# move 'Drug' out of the multi index to allow for sorting
df.reset_index(level=[1], inplace=True)

# Sort the 'Quantity' descending order, and the 'Drug' in ascending order,
# then we can select the first 'PostCode' for our result
df.sort_values(['Quantity','Drug'], ascending=[False, True], inplace=True)

df.groupby('PostCode').first()

           Drug Quantity
PostCode        
P1          D1  0.571429
P2          D1  0.500000
P3          D2  1.000000

谢谢,有很多资料要研究。真的很感激。@user007这是个好问题,我自己也学到了一些东西。谢谢
# sort by PostCode, Drug
df = drugs_prescriptions.groupby(['PostCode', 'Drug']).agg('sum')
df = df.groupby(['PostCode']).apply(lambda x: x.sort_values(['Quantity', 'Drug'], ascending=[False, True]))

# select first value by PostCode
# reset index in order to have drug in the output as well
df.reset_index(level=[1], inplace=True)
df = df.groupby(['PostCode']).first()

# calculate percentage of total by PostCode
allQuantities = drugs_prescriptions.groupby(['PostCode']).agg('sum')
df['Quantity'] = df.apply(lambda row: row['Quantity']/allQuantities.loc[row.name], axis=1)
# setting string to integer
df.Quantity = df.Quantity.astype('int')

# create a mulitiindex
df.set_index(['PostCode', 'Drug'], inplace=True)

# use transform to divide the sum of the 'Drug' level by the 'PostCode' level
df = df.groupby(level=[0,1]).transform('sum') / df.groupby(level=0).transform('sum')

# move 'Drug' out of the multi index to allow for sorting
df.reset_index(level=[1], inplace=True)

# Sort the 'Quantity' descending order, and the 'Drug' in ascending order,
# then we can select the first 'PostCode' for our result
df.sort_values(['Quantity','Drug'], ascending=[False, True], inplace=True)

df.groupby('PostCode').first()

           Drug Quantity
PostCode        
P1          D1  0.571429
P2          D1  0.500000
P3          D2  1.000000