Python Pandas groupby, rank, then assign value based on custom rank

大兔子大兔子 提交于 2019-12-11 03:35:56

问题


Problem Setup

The pandas Dataframe

df = pd.DataFrame({'Group': ['A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'], 'Subgroup': ['Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 2', 'Group 2', 'Group 2'], 'Keyword': ['kw 1', 'kw 1', 'kw 1', 'kw 2', '+kw +2', 'kw 2', 'kw 3', 'kw 3', 'kw 3'], 'Normalized': ['kw 1', 'kw 1', 'kw 1', 'kw 2', 'kw 2', 'kw 2', 'kw 3', 'kw 3', 'kw 3'], 'Criterion Type': ['Exact', 'Phrase', 'Broad', 'Phrase', 'Broadified', 'Exact', 'Broad', 'Exact', 'Phrase'], 'Max CPC': [1.62, 1.73, 0.87, 1.70, 0.85, 1.60, 0.99, 1.58, 1.68], 'CPC Rank': [2, 1, 3, 1, 3, 2, 3, 2, 1], 'Type Rank': [1, 2, 3, 2, 3, 1, 3, 1, 2]})

This to get the columns in the right spot:

df = df[['Group', 'Subgroup', 'Keyword', 'Normalized', 'Criterion Type', 'Max CPC', 'CPC Rank', 'Type Rank']]

The goal

groupby ['Group', 'Subgroup', 'Normalized'], then rank the Max CPCs. Next, I want to map the Max CPC associated to the CPC Rank to the Type Rank which is determined based on Criterion Type and my own custom rank: {'Exact':1, 'Phrase':2, 'Broadified':3, 'Broad':4}

The result would be the New CPC column with its appropriate Max CPC.


回答1:


I have sorted the values inside each group and assigned the sorted values using index. Is this what you want?

df['new CPC'] = -1
parts = []
grouped = df.groupby(['Group', 'Subgroup', 'Normalized'])
for name, group in grouped:
    type_rank_index = group.sort(columns='Type Rank').index
    cpc_rank_index = group.sort(columns='CPC Rank').index
    group.loc[type_rank_index, 'new CPC'] = group.loc[cpc_rank_index, 'Max CPC']
    parts.append(group)

result = pd.concat(parts)



回答2:


import pandas as pd
import numpy as np

df = pd.DataFrame({'Group': ['A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A'], 'Subgroup': ['Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 1', 'Group 2', 'Group 2', 'Group 2'], 'Keyword': ['kw 1', 'kw 1', 'kw 1', 'kw 2', '+kw +2', 'kw 2', 'kw 3', 'kw 3', 'kw 3'], 'Normalized': ['kw 1', 'kw 1', 'kw 1', 'kw 2', 'kw 2', 'kw 2', 'kw 3', 'kw 3', 'kw 3'], 'Criterion Type': ['Exact', 'Phrase', 'Broad', 'Phrase', 'Broadified', 'Exact', 'Broad', 'Exact', 'Phrase'], 'Max CPC': [1.62, 1.73, 0.87, 1.70, 0.85, 1.60, 0.99, 1.58, 1.68], 'CPC Rank': [2, 1, 3, 1, 3, 2, 3, 2, 1], 'Type Rank': [1, 2, 3, 2, 3, 1, 3, 1, 2]})
df = df[['Group', 'Subgroup', 'Keyword', 'Normalized', 'Criterion Type', 'Max CPC', 'CPC Rank', 'Type Rank']]

#Sort by custom priority based on their Criterion Type
df = df.sort(['Group', 'Subgroup', 'Normalized', 'Type Rank'])
#Reset index and drop old one
df = df.reset_index(drop=True)
print(df)
#Create df1 which is a Series of the Max CPC column in its correctly ranked order
df1 = df.sort(['Group', 'Subgroup', 'Normalized', 'CPC Rank'])['Max CPC']
#Reset index and drop old one
df1 = df1.reset_index(drop=True)
print(df1)

#Add the df1 Series to df and name the column New CPC
df['New CPC'] = df1

print(df)

This is by far the most efficient solution to this problem. The hard part was realizing that I could sort df by the Type Rank so the Criterion Type rows were ordered by their rank. This meant I wanted the highest Max CPC to apply to the first, the second highest Max CPC to the second, and so on.

Then all I had to do was create a Max CPC Series sorted by CPC Rank.

Lastly, add this Series to the existing df.




回答3:


try this one

def group_rank(df):
    # first of all you've to rank according to `Max CPC`
    df['CPC Rank'] = df['Max CPC'].rank(ascending = False)
    # create the mapping
    mapping = pd.Series(data=df['Max CPC'].values , index= df['CPC Rank'].values)
    # create new column according to your ranking
    df['New CPC'] = df['Type Rank'].map(mapping)
    return df

df.groupby(['Group', 'Subgroup', 'Normalized']).apply(group_rank)


来源:https://stackoverflow.com/questions/32411615/python-pandas-groupby-rank-then-assign-value-based-on-custom-rank

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!