python

时间:2018-05-08 11:37:10

标签: python pandas

我有以下数据:

player_id   broadcast_month_id  runs_tier
67          201803              100s
67          201803              400s
67          201802              50s
67          201802              100s
67          201801              50s
67          201712              50s
67          201711              50s
67          201710              50s
67          201709              50s
67          201708              50s
67          201707              50s
67          201706              50s
67          201705              50s
67          201704              50s
67          201704              Others

我想找出数据集中每个玩家的最新runs_tier(此示例仅包含1个玩家,但原始数据集有大约500个玩家)

在读取数据后,我按照player_id进行分组,然后根据月份划分并计算每个层次的月数,如下所示:

run_tier = df_tier.pivot_table(index=['player_id'],columns=['runs_tier'],aggfunc='count',fill_value=0)\
                    .xs('broadcast_month_id', axis=1, drop_level=True)

我可以获得玩家最多月份的等级,如下所示:

run_tier['latest'] = df_tier.sort_values('player_id').groupby('player_id')['runs_tier'].tail(1).values

如何获得最新级别的播放器? 根据以上数据,这个玩家最新的runs_tier是100s 有人可以帮帮我吗?

household_id    100s    400s    50s Others  latest
67          2       1       11  1       100s

如果像前两个记录一样重复,我会在排序日期后排在最前面。

2 个答案:

答案 0 :(得分:2)

首先考虑使用groupby().transform() df_tier 中创建最新列,然后运行pivot_table而不需要.xs(),然后条件筛选groupby().min上的新列分配:

# NEW COLUMN FOR LATEST broadcast_month_id
df_tier['latest'] = df_tier.groupby('player_id')['broadcast_month_id'].transform('max')

# PIVOT TABLE (with values arg)
run_tier = df_tier.pivot_table(index='player_id', columns='runs_tier', 
                               values='broadcast_month_id',
                               aggfunc='count', fill_value=0).rename_axis(None)

# NEW COLUMN FOR MIN runs_tier IN LATEST broadcast_month_id
run_tier['latest'] = df_tier[df_tier['latest']==df_tier['broadcast_month_id']]\
                           .groupby('player_id')['runs_tier'].min()

print(run_tier)
# runs_tier  100s  400s  50s  Others latest
# 67            2     1   11       1   100s

答案 1 :(得分:1)

如果我理解正确......

首先,我们必须能够对runs_tier进行排序,因此请将其设为数字​​,移除s并将Others设置为nan

>>> df
    broadcast_month_id  player_id runs_tier
0               201803         67      100s
1               201803         67      400s
2               201802         67       50s
3               201802         67      100s
4               201801         67       50s
..                 ...        ...       ...
10              201707         67       50s
11              201706         67       50s
12              201705         67       50s
13              201704         67       50s
14              201704         67    Others

[15 rows x 3 columns]

>>> df['numeric_tier'] = pd.to_numeric(df['runs_tier'].apply(lambda x: x[:-1]), errors='coerce')
>>> df
    broadcast_month_id  player_id runs_tier  numeric_tiers
0               201803         67      100s        100.000
1               201803         67      400s        400.000
2               201802         67       50s         50.000
3               201802         67      100s        100.000
4               201801         67       50s         50.000
..                 ...        ...       ...            ...
10              201707         67       50s         50.000
11              201706         67       50s         50.000
12              201705         67       50s         50.000
13              201704         67       50s         50.000
14              201704         67    Others            nan

[15 rows x 4 columns]

现在我们可以对数据帧进行排序,以便每个玩家的第一次出现是最新的最高层

df = df.sort_values(['player_id', 'broadcast_month_id', 'numeric_tiers'], ascending=[True, False, True])

并仅选择第一次出现:

>>> df = df[~df.duplicated('player_id')]
>>> df
   broadcast_month_id  player_id runs_tier  numeric_tiers
0              201803         67      100s        100.000

然后我们可以加入

>>> run_tier['lastest'] = df.set_index('player_id')['runs_tier'] 
>>> run_tier
runs_tier  100s  400s  50s  Others lastest                                                                                       
player_id                                                                                                                        
67            2     1   11       1    100s