熊猫按多列排名

Ano*_*oop 6 python rank python-3.x pandas

我试图根据两列对大熊猫数据框进行排名.我可以根据一列对其进行排名,但如何根据两列对其进行排名?'SaleCount',然后'TotalRevenue'?

import pandas as pd

df = pd.DataFrame({'TotalRevenue':[300,9000,1000,750,500,2000,0,600,50,500],
    'Date':['2016-12-02' for i in range(10)],
    'SaleCount':[10,100,30,35,20,100,0,30,2,20],
    'shops':['S3','S2','S1','S5','S4','S8','S6','S7','S9','S10']})

df['Rank'] = df.SaleCount.rank(method='dense',ascending = False).astype(int)

#df['Rank'] = df.TotalRevenue.rank(method='dense',ascending = False).astype(int)
df.sort_values(['Rank'], inplace=True)

print(df)
Run Code Online (Sandbox Code Playgroud)

电流输出:

    Date        SaleCount   TotalRevenue    shops   Rank
1   2016-12-02  100          9000            S2      1
5   2016-12-06  100          2000            S8      1
3   2016-12-04  35           750             S5      2
2   2016-12-03  30           1000            S1      3
7   2016-12-08  30           600             S7      3
9   2016-12-10  20           500             S10     4
4   2016-12-05  20           500             S4      4
0   2016-12-01  10           300             S3      5
8   2016-12-09  2            50              S9      6
6   2016-12-07  0            0               S6      7
Run Code Online (Sandbox Code Playgroud)

我正在尝试生成这样的输出:

    Date        SaleCount   TotalRevenue    shops   Rank
1   2016-12-02  100          9000            S2      1
5   2016-12-02  100          2000            S8      2
3   2016-12-02  35           750             S5      3
2   2016-12-02  30           1000            S1      4
7   2016-12-02  30           600             S7      5
9   2016-12-02  20           500             S10     6
4   2016-12-02  20           500             S4      6
0   2016-12-02  10           300             S3      7
8   2016-12-02  2            50              S9      8
6   2016-12-02  0            0               S6      9
Run Code Online (Sandbox Code Playgroud)

Nic*_*eli 10

另一种方法是将两个感兴趣的列进行类型转换str,并通过连接它们来组合它们.将它们转换回数值,以便根据它们的大小区分它们.

method=dense,重复值的排名将保持不变.(这里:6)

由于您希望按降序对这些进行排名,因此指定ascending=Falsein Series.rank()将使您获得所需的结果.

col1 = df["SaleCount"].astype(str) 
col2 = df["TotalRevenue"].astype(str)
df['Rank'] = (col1+col2).astype(int).rank(method='dense', ascending=False).astype(int)
df.sort_values('Rank')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 请注意,字符串连接两列 `(col1+col2` *而无需* 将 `astype(int)` 转换为危险的字符串会很危险,因为 '30' > '100' 在 string-land 排序顺序中。 (2认同)

B. *_* M. 10

这样做的通用方法是将所需的字段分组在一个元组中,无论类型如何。

df["Rank"] = df[["SaleCount","TotalRevenue"]].apply(tuple,axis=1)\
             .rank(method='dense',ascending=False).astype(int)

df.sort_values("Rank")

   TotalRevenue        Date  SaleCount shops  Rank
1          9000  2016-12-02        100    S2     1
5          2000  2016-12-02        100    S8     2
3           750  2016-12-02         35    S5     3
2          1000  2016-12-02         30    S1     4
7           600  2016-12-02         30    S7     5
4           500  2016-12-02         20    S4     6
9           500  2016-12-02         20   S10     6
0           300  2016-12-02         10    S3     7
8            50  2016-12-02          2    S9     8
6             0  2016-12-02          0    S6     9
Run Code Online (Sandbox Code Playgroud)

  • 在这种情况下,如果我们想按商店等另一列进行分组怎么办? (2认同)

piR*_*red 7

pd.factorize将为iterable的每个唯一元素生成唯一值.我们只需按照我们想要的顺序排序,然后进行分解.为了执行多个列,我们将排序结果转换为元组.

cols = ['SaleCount', 'TotalRevenue']
tups = df[cols].sort_values(cols, ascending=False).apply(tuple, 1)
f, i = pd.factorize(tups)
factorized = pd.Series(f + 1, tups.index)

df.assign(Rank=factorized)

         Date  SaleCount  TotalRevenue shops  Rank
1  2016-12-02        100          9000    S2     1
5  2016-12-02        100          2000    S8     2
3  2016-12-02         35           750    S5     3
2  2016-12-02         30          1000    S1     4
7  2016-12-02         30           600    S7     5
4  2016-12-02         20           500    S4     6
9  2016-12-02         20           500   S10     6
0  2016-12-02         10           300    S3     7
8  2016-12-02          2            50    S9     8
6  2016-12-02          0             0    S6     9
Run Code Online (Sandbox Code Playgroud)


ALo*_*llz 6

sort_values+GroupBy.ngroup

这将给出dense排名。

应在分组之前按所需顺序对列进行排序。sort=False在 then中指定groupby会尊重这种排序,以便组按照它们在排序的 DataFrame 中出现的顺序进行标记。

cols = ['SaleCount', 'TotalRevenue']
df['Rank'] = df.sort_values(cols, ascending=False).groupby(cols, sort=False).ngroup() + 1
Run Code Online (Sandbox Code Playgroud)

输出:

print(df.sort_values('Rank'))

   TotalRevenue        Date  SaleCount shops  Rank
1          9000  2016-12-02        100    S2     1
5          2000  2016-12-02        100    S8     2
3           750  2016-12-02         35    S5     3
2          1000  2016-12-02         30    S1     4
7           600  2016-12-02         30    S7     5
4           500  2016-12-02         20    S4     6
9           500  2016-12-02         20   S10     6
0           300  2016-12-02         10    S3     7
8            50  2016-12-02          2    S9     8
6             0  2016-12-02          0    S6     9
Run Code Online (Sandbox Code Playgroud)