首页 > 解决方案 > pandas - 如果前 2 名则为 1

问题描述

我有一个数据框如下:

df = pd.DataFrame({'Date': ['02/01/2019', '03/01/2019', '04/01/2019', '07/01/2019', '08/01/2019', '09/01/2019', '10/01/2019', '11/01/2019', '14/01/2019', '15/01/2019'],
                   'VOD': [3, 2.3, 2, 1.8, 2, 4, 5, 4, 3, 1],
                   'BBY': [0.9, 1, 1.2, 1, 1, 2.3, 2.4, 2.5, 3, 2.9],
                   'STJ': [4, 4.2, 4.3, 4.4, 3.5, 3, 2, 1, 1.2, 2],
                   'RBS': [0.5, 0.6, 0.7, 0.6, 1, 1.2, 1.3, 1.4, 1.5, 2]})

从这个数据框中,我可以按列对每一行进行排名,如下所示:

df1 = df.rank(1, ascending=False, method='first')

我正在尝试将 1 分配给排名前两位(在第一行,这将是 VOD 和 STJ),而将 0 分配给其他排名。

我的目标是最终得到如下表格:

result = pd.DataFrame({'Date': ['02/01/2019', '03/01/2019', '04/01/2019', '07/01/2019', '08/01/2019', '09/01/2019', '10/01/2019', '11/01/2019', '14/01/2019', '15/01/2019'],
                       'VOD': [1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
                       'BBY': [0,0,0,0,0,0,1,1,1,1],
                       'STJ': [1,1,1,1,1,1,0,0,0,1],
                       'RBS': [0,0,0,0,0,0,0,0,0,0]})

我认为 if 语句会起作用,但无法与 rank() 一起使用。想法非常受欢迎。

标签: pythonpandas

解决方案


DataFrame.isin与转换为整数一起True/False用于映射1/0

cols = ['VOD','BBY','STJ','RBS']
df[cols] = df[cols].rank(axis=1, ascending=False, method='first').isin([1,2]).astype(int)

或使用numpy.where

df[cols] = np.where(df[cols].rank(axis=1, ascending=False, method='first').isin([1,2]), 1, 0)

print (df)
         Date  VOD  BBY  STJ  RBS
0  02/01/2019    1    0    1    0
1  03/01/2019    1    0    1    0
2  04/01/2019    1    0    1    0
3  07/01/2019    1    0    1    0
4  08/01/2019    1    0    1    0
5  09/01/2019    1    0    1    0
6  10/01/2019    1    1    0    0
7  11/01/2019    1    1    0    0
8  14/01/2019    1    1    0    0
9  15/01/2019    0    1    1    0

推荐阅读