Python 3:使用多列对数据框进行排名
Python 3: Rank dataframe using multiple columns
我有一个这样的数据框"df_orders_raw":
ORD_KEY ORD_DT_KEY ORD_TM_KEY SKU_KEY QTY
933915294 7598 13 401550750 1
933915294 7598 13 409868344 1
933915294 7598 13 428852481 1
933919765 7598 13 432771563 2
933892844 7598 24 429377565 1
933892844 7598 24 413100006 1
933892844 7598 24 433950159 1
933908232 7598 38 427905127 1
933882107 7598 40 415639133 1
933882107 7598 40 428839526 1
933918543 7598 44 429503890 1
933918543 7598 44 429501262 1
我想按ORD_DT_KEY、ORD_TM_KEY、ORD_KEY 向此帧排名数据添加一个ORD_RANK 列,意思是,数据应按[=28= 分组] 首先,然后 ORD_TM_KEY 将打破第一级关系,然后是 ORD_KEY。
结果排名应如下所示:
ORD_KEY ORD_DT_KEY ORD_TM_KEY SKU_KEY QTY ORD_RANK
933915294 7598 13 401550750 1 1
933915294 7598 13 409868344 1 1
933915294 7598 13 428852481 1 1
933919765 7598 13 432771563 2 2
933892844 7598 24 429377565 1 3
933892844 7598 24 413100006 1 3
933892844 7598 24 433950159 1 3
933908232 7598 38 427905127 1 4
933882107 7598 40 415639133 1 5
933882107 7598 40 428839526 1 5
933918543 7598 44 429503890 1 6
933918543 7598 44 429501262 1 6
阅读了一堆类似的 QnA 后,我当前的代码如下所示:
df_orders = df_orders_raw.copy()
col1 = df_orders['ORD_DT_KEY'].astype(str)
col2 = df_orders['ORD_TM_KEY'].astype(str)
col3 = df_orders['ORD_KEY'].astype(str)
key = col1+col2+col3
df_orders['ORD_RANK'] = (key).astype(float).rank(method='dense').astype(int)
此代码适用于大多数情况,但当键变得非常大(10^17 或更大)时开始中断,因为它开始四舍五入浮点数。它在 Python 2.7 中工作,因为我使用 "long" 而不是 "float",但在 Python 3.5 中不支持。如果我使用 (key).astype(int),它会抛出一个 OverflowError。在阅读了类似的问题后,人们建议使用 float 但这给了我另一个问题。我如何修改代码以使其适用于所有情况?
使用ngroup
df['ORD_RANK']=df.groupby(['ORD_DT_KEY','ORD_TM_KEY','ORD_KEY']).ngroup()+1
df
Out[1010]:
ORD_KEY ORD_DT_KEY ORD_TM_KEY SKU_KEY QTY ORD_RANK
0 933915294 7598 13 401550750 1 1
1 933915294 7598 13 409868344 1 1
2 933915294 7598 13 428852481 1 1
3 933919765 7598 13 432771563 2 2
4 933892844 7598 24 429377565 1 3
5 933892844 7598 24 413100006 1 3
6 933892844 7598 24 433950159 1 3
7 933908232 7598 38 427905127 1 4
8 933882107 7598 40 415639133 1 5
9 933882107 7598 40 428839526 1 5
10 933918543 7598 44 429503890 1 6
11 933918543 7598 44 429501262 1 6
我有一个这样的数据框"df_orders_raw":
ORD_KEY ORD_DT_KEY ORD_TM_KEY SKU_KEY QTY
933915294 7598 13 401550750 1
933915294 7598 13 409868344 1
933915294 7598 13 428852481 1
933919765 7598 13 432771563 2
933892844 7598 24 429377565 1
933892844 7598 24 413100006 1
933892844 7598 24 433950159 1
933908232 7598 38 427905127 1
933882107 7598 40 415639133 1
933882107 7598 40 428839526 1
933918543 7598 44 429503890 1
933918543 7598 44 429501262 1
我想按ORD_DT_KEY、ORD_TM_KEY、ORD_KEY 向此帧排名数据添加一个ORD_RANK 列,意思是,数据应按[=28= 分组] 首先,然后 ORD_TM_KEY 将打破第一级关系,然后是 ORD_KEY。
结果排名应如下所示:
ORD_KEY ORD_DT_KEY ORD_TM_KEY SKU_KEY QTY ORD_RANK
933915294 7598 13 401550750 1 1
933915294 7598 13 409868344 1 1
933915294 7598 13 428852481 1 1
933919765 7598 13 432771563 2 2
933892844 7598 24 429377565 1 3
933892844 7598 24 413100006 1 3
933892844 7598 24 433950159 1 3
933908232 7598 38 427905127 1 4
933882107 7598 40 415639133 1 5
933882107 7598 40 428839526 1 5
933918543 7598 44 429503890 1 6
933918543 7598 44 429501262 1 6
阅读了一堆类似的 QnA 后,我当前的代码如下所示:
df_orders = df_orders_raw.copy()
col1 = df_orders['ORD_DT_KEY'].astype(str)
col2 = df_orders['ORD_TM_KEY'].astype(str)
col3 = df_orders['ORD_KEY'].astype(str)
key = col1+col2+col3
df_orders['ORD_RANK'] = (key).astype(float).rank(method='dense').astype(int)
此代码适用于大多数情况,但当键变得非常大(10^17 或更大)时开始中断,因为它开始四舍五入浮点数。它在 Python 2.7 中工作,因为我使用 "long" 而不是 "float",但在 Python 3.5 中不支持。如果我使用 (key).astype(int),它会抛出一个 OverflowError。在阅读了类似的问题后,人们建议使用 float 但这给了我另一个问题。我如何修改代码以使其适用于所有情况?
使用ngroup
df['ORD_RANK']=df.groupby(['ORD_DT_KEY','ORD_TM_KEY','ORD_KEY']).ngroup()+1
df
Out[1010]:
ORD_KEY ORD_DT_KEY ORD_TM_KEY SKU_KEY QTY ORD_RANK
0 933915294 7598 13 401550750 1 1
1 933915294 7598 13 409868344 1 1
2 933915294 7598 13 428852481 1 1
3 933919765 7598 13 432771563 2 2
4 933892844 7598 24 429377565 1 3
5 933892844 7598 24 413100006 1 3
6 933892844 7598 24 433950159 1 3
7 933908232 7598 38 427905127 1 4
8 933882107 7598 40 415639133 1 5
9 933882107 7598 40 428839526 1 5
10 933918543 7598 44 429503890 1 6
11 933918543 7598 44 429501262 1 6