在 pandas 中每月获取前 N 个项目
Get Top N items per month in pandas
我有以下数据框(与我原来的数据框相比,这是一个相当精简的样本)。
year month id revenue
80496 2020 2 16 536000.00
84222 2020 1 2758 430344.66
84223 2020 1 2758 679945.17
84224 2020 1 2758 543982.82
84225 2020 3 2758 287728.00
84226 2020 3 2758 321874.00
84227 2020 3 2758 408128.00
84230 2020 3 2758 458304.00
84231 2020 3 2758 332528.00
85309 2020 2 1560 277233.84
85312 2020 2 1560 419910.83
85876 2020 3 2890 333281.00
90690 2020 1 1304 306297.32
90691 2020 1 1304 391399.67
90698 2020 1 1304 314511.00
90699 2020 2 1304 598394.98
90701 2020 2 1304 391659.34
90702 2020 2 1304 420196.17
90703 2020 2 1304 390432.01
90705 2020 2 1304 485868.16
90706 2020 2 1304 340244.66
91066 2020 2 3738 426222.33
92039 2020 2 1273 269514.00
92040 2020 2 1273 399330.00
92043 2020 3 1273 845502.01
92044 2020 3 1273 285688.00
92045 2020 2 1304 471677.67
92053 2020 2 1304 306994.32
92055 2020 2 1304 514140.01
92058 2020 2 1304 670594.83
92059 2020 2 1304 313311.17
92060 2020 2 1304 264825.32
92061 2020 2 1304 417365.50
92063 2020 3 2758 460628.00
92064 2020 3 2758 270060.00
92074 2020 2 4354 626157.00
92075 2020 2 4354 1225539.99
92078 2020 3 2911 381026.67
92079 2020 3 2911 325471.67
92080 2020 3 2911 383008.33
92081 2020 3 2911 267538.66
92082 2020 3 2911 383789.17
92083 2020 3 2911 352452.50
92084 2020 3 2911 279040.84
92085 2020 3 2911 367950.82
92087 2020 2 130 284714.26
92088 2020 2 130 600318.97
92089 2020 2 130 270437.93
92091 2020 2 130 272350.83
92092 2020 2 130 346533.36
92093 2020 2 130 294939.32
92100 2020 2 134 303719.16
92101 2020 3 134 367001.67
92112 2020 3 1561 276828.00
92113 2020 3 1561 279312.01
92114 2020 3 1625 294794.50
92119 2020 3 1625 592332.50
92126 2020 2 2890 620486.67
92128 2020 3 2890 680190.00
92130 2020 3 2890 418707.33
92131 2020 3 2890 328754.99
92132 2020 3 2890 339958.00
92137 2020 3 2890 554962.00
92138 2020 3 2890 365953.34
92139 2020 3 2890 486639.16
92140 2020 3 2890 1610025.83
92141 2020 3 2890 589236.49
我正在尝试获取每年和每月的前 2 个 ID。因此,例如,我们的想法是获得以下 df。我在这里的主要问题是获取前 n 个以及日期,因为 nlargest
方法适用于 pd.Series 或数据框(但在这种情况下,您不能为多个条件传递列表) .
year month id revenue
0 2020 3 2890 6626149.47
1 2020 3 2758 4428253.33
691 2020 2 1304 6997646.32
692 2020 2 130 2229204.96
1785 2020 1 2758 1749250.49
1786 2020 1 1304 1581520.32
到目前为止,我的代码是:
df.groupby(by=['year', 'month', 'id'])[['revenue']].agg({'revenue': 'sum'}).sort_values(by=['year', 'month', 'revenue'], ascending=False).reset_index()
您可以使用 GroupBy.apply
为每个组调用一个函数(每个组都是一个单独的数据帧)。
top_two_per_year_month = df.groupby(['year', 'month'], as_index=False).apply(lambda x: x.sort_values('revenue', ascending=False)[0:2]).droplevel(0)
输出:
>>> top_two_per_year_month
year month id revenue
84223 2020 1 2758 679945.17
84224 2020 1 2758 543982.82
92075 2020 2 4354 1225539.99
92058 2020 2 1304 670594.83
92140 2020 3 2890 1610025.83
92043 2020 3 1273 845502.01
或者,使用 nlargest
,正如@LarryTheLlama 建议的那样:
top_two_per_year_month = df.groupby(['year', 'month']).apply(lambda x: x['revenue'].nlargest(2))
输出:
>>> top_two_per_year_month
year month
2020 1 84223 679945.17
84224 543982.82
2 92075 1225539.99
92058 670594.83
3 92140 1610025.83
92043 845502.01
Name: revenue, dtype: float64
>>> top_two_per_year_month.reset_index().rename({'level_2': 'id'}, axis=1)
year month id revenue
0 2020 1 84223 679945.17
1 2020 1 84224 543982.82
2 2020 2 92075 1225539.99
3 2020 2 92058 670594.83
4 2020 3 92140 1610025.83
5 2020 3 92043 845502.01
一种选择是在分组前对列进行排序,并使用nth
函数:
(df.sort_values(['year', 'month','revenue', 'id'],
ascending=[True, True, False, False])
.groupby(['year', 'month'],
as_index = False,
sort = False)
.nth([0,1])
)
year month id revenue
84223 2020 1 2758 679945.17
84224 2020 1 2758 543982.82
92075 2020 2 4354 1225539.99
92058 2020 2 1304 670594.83
92140 2020 3 2890 1610025.83
92043 2020 3 1273 845502.01
你不需要申请,排序数据帧,groupby 然后使用 head
:
df.sort_values(['year', 'month', 'revenue'], ascending=[True, True, False])\
.groupby(['year', 'month']).head(2`)
输出:
year month id revenue
84223 2020 1 2758 679945.17
84224 2020 1 2758 543982.82
92075 2020 2 4354 1225539.99
92058 2020 2 1304 670594.83
92140 2020 3 2890 1610025.83
92043 2020 3 1273 845502.01
我有以下数据框(与我原来的数据框相比,这是一个相当精简的样本)。
year month id revenue
80496 2020 2 16 536000.00
84222 2020 1 2758 430344.66
84223 2020 1 2758 679945.17
84224 2020 1 2758 543982.82
84225 2020 3 2758 287728.00
84226 2020 3 2758 321874.00
84227 2020 3 2758 408128.00
84230 2020 3 2758 458304.00
84231 2020 3 2758 332528.00
85309 2020 2 1560 277233.84
85312 2020 2 1560 419910.83
85876 2020 3 2890 333281.00
90690 2020 1 1304 306297.32
90691 2020 1 1304 391399.67
90698 2020 1 1304 314511.00
90699 2020 2 1304 598394.98
90701 2020 2 1304 391659.34
90702 2020 2 1304 420196.17
90703 2020 2 1304 390432.01
90705 2020 2 1304 485868.16
90706 2020 2 1304 340244.66
91066 2020 2 3738 426222.33
92039 2020 2 1273 269514.00
92040 2020 2 1273 399330.00
92043 2020 3 1273 845502.01
92044 2020 3 1273 285688.00
92045 2020 2 1304 471677.67
92053 2020 2 1304 306994.32
92055 2020 2 1304 514140.01
92058 2020 2 1304 670594.83
92059 2020 2 1304 313311.17
92060 2020 2 1304 264825.32
92061 2020 2 1304 417365.50
92063 2020 3 2758 460628.00
92064 2020 3 2758 270060.00
92074 2020 2 4354 626157.00
92075 2020 2 4354 1225539.99
92078 2020 3 2911 381026.67
92079 2020 3 2911 325471.67
92080 2020 3 2911 383008.33
92081 2020 3 2911 267538.66
92082 2020 3 2911 383789.17
92083 2020 3 2911 352452.50
92084 2020 3 2911 279040.84
92085 2020 3 2911 367950.82
92087 2020 2 130 284714.26
92088 2020 2 130 600318.97
92089 2020 2 130 270437.93
92091 2020 2 130 272350.83
92092 2020 2 130 346533.36
92093 2020 2 130 294939.32
92100 2020 2 134 303719.16
92101 2020 3 134 367001.67
92112 2020 3 1561 276828.00
92113 2020 3 1561 279312.01
92114 2020 3 1625 294794.50
92119 2020 3 1625 592332.50
92126 2020 2 2890 620486.67
92128 2020 3 2890 680190.00
92130 2020 3 2890 418707.33
92131 2020 3 2890 328754.99
92132 2020 3 2890 339958.00
92137 2020 3 2890 554962.00
92138 2020 3 2890 365953.34
92139 2020 3 2890 486639.16
92140 2020 3 2890 1610025.83
92141 2020 3 2890 589236.49
我正在尝试获取每年和每月的前 2 个 ID。因此,例如,我们的想法是获得以下 df。我在这里的主要问题是获取前 n 个以及日期,因为 nlargest
方法适用于 pd.Series 或数据框(但在这种情况下,您不能为多个条件传递列表) .
year month id revenue
0 2020 3 2890 6626149.47
1 2020 3 2758 4428253.33
691 2020 2 1304 6997646.32
692 2020 2 130 2229204.96
1785 2020 1 2758 1749250.49
1786 2020 1 1304 1581520.32
到目前为止,我的代码是:
df.groupby(by=['year', 'month', 'id'])[['revenue']].agg({'revenue': 'sum'}).sort_values(by=['year', 'month', 'revenue'], ascending=False).reset_index()
您可以使用 GroupBy.apply
为每个组调用一个函数(每个组都是一个单独的数据帧)。
top_two_per_year_month = df.groupby(['year', 'month'], as_index=False).apply(lambda x: x.sort_values('revenue', ascending=False)[0:2]).droplevel(0)
输出:
>>> top_two_per_year_month
year month id revenue
84223 2020 1 2758 679945.17
84224 2020 1 2758 543982.82
92075 2020 2 4354 1225539.99
92058 2020 2 1304 670594.83
92140 2020 3 2890 1610025.83
92043 2020 3 1273 845502.01
或者,使用 nlargest
,正如@LarryTheLlama 建议的那样:
top_two_per_year_month = df.groupby(['year', 'month']).apply(lambda x: x['revenue'].nlargest(2))
输出:
>>> top_two_per_year_month
year month
2020 1 84223 679945.17
84224 543982.82
2 92075 1225539.99
92058 670594.83
3 92140 1610025.83
92043 845502.01
Name: revenue, dtype: float64
>>> top_two_per_year_month.reset_index().rename({'level_2': 'id'}, axis=1)
year month id revenue
0 2020 1 84223 679945.17
1 2020 1 84224 543982.82
2 2020 2 92075 1225539.99
3 2020 2 92058 670594.83
4 2020 3 92140 1610025.83
5 2020 3 92043 845502.01
一种选择是在分组前对列进行排序,并使用nth
函数:
(df.sort_values(['year', 'month','revenue', 'id'],
ascending=[True, True, False, False])
.groupby(['year', 'month'],
as_index = False,
sort = False)
.nth([0,1])
)
year month id revenue
84223 2020 1 2758 679945.17
84224 2020 1 2758 543982.82
92075 2020 2 4354 1225539.99
92058 2020 2 1304 670594.83
92140 2020 3 2890 1610025.83
92043 2020 3 1273 845502.01
你不需要申请,排序数据帧,groupby 然后使用 head
:
df.sort_values(['year', 'month', 'revenue'], ascending=[True, True, False])\
.groupby(['year', 'month']).head(2`)
输出:
year month id revenue
84223 2020 1 2758 679945.17
84224 2020 1 2758 543982.82
92075 2020 2 4354 1225539.99
92058 2020 2 1304 670594.83
92140 2020 3 2890 1610025.83
92043 2020 3 1273 845502.01