按等级扭曲数据帧

时间:2016-09-21 00:00:12

标签: python pandas numpy

设置

考虑数据框df

np.random.seed([3,1415])
df = pd.DataFrame(np.random.rand(4, 5), columns=list('ABCDE'))
df

          A         B         C         D         E
0  0.444939  0.407554  0.460148  0.465239  0.462691
1  0.016545  0.850445  0.817744  0.777962  0.757983
2  0.934829  0.831104  0.879891  0.926879  0.721535
3  0.117642  0.145906  0.199844  0.437564  0.100702

我想要一个数据框,其中列是排名,每行按排名顺序排列['A', 'B', 'C', 'D', 'E']

排名

df.rank(1).astype(int)

   A  B  C  D  E
0  2  1  3  5  4
1  1  5  4  3  2
2  5  2  3  4  1
3  2  3  4  5  1

预期结果

0  1  2  3  4  5
0  B  A  C  E  D
1  A  E  D  C  B
2  E  B  C  D  A
3  E  A  B  C  D

进一步说明

我想看到每一行按顺序显示列。第一行首先有'B',因为它在原始数据框的那一行中有第一个排名。

3 个答案:

答案 0 :(得分:3)

以这种方式:

In [90]: df
Out[90]: 
          A         B         C         D         E
0  0.444939  0.407554  0.460148  0.465239  0.462691
1  0.016545  0.850445  0.817744  0.777962  0.757983
2  0.934829  0.831104  0.879891  0.926879  0.721535
3  0.117642  0.145906  0.199844  0.437564  0.100702

In [91]: df2 = df.apply(lambda row: df.columns[np.argsort(row)], axis=1)

In [92]: df2
Out[92]: 
   A  B  C  D  E
0  B  A  C  E  D
1  A  E  D  C  B
2  E  B  C  D  A
3  E  A  B  C  D

新的DataFrame与df具有相同的列索引,但可以修复:

In [93]: df2.columns = range(1, 1 + df2.shape[1])

In [94]: df2
Out[94]: 
   1  2  3  4  5
0  B  A  C  E  D
1  A  E  D  C  B
2  E  B  C  D  A
3  E  A  B  C  D

这是另一种方式。这个将DataFrame转换为numpy数组,在轴1上应用argsort,使用它来索引df.columns,并将结果放回到DataFrame中。

In [110]: pd.DataFrame(df.columns[np.array(df).argsort(axis=1)], columns=range(1, 1 + df.shape[1]))
Out[110]: 
   1  2  3  4  5
0  B  A  C  E  D
1  A  E  D  C  B
2  E  B  C  D  A
3  E  A  B  C  D

答案 1 :(得分:1)

这是另一种方式。

In [5]: df1 = df.rank(1).astype(int)

In [6]: df3 = df1.replace({rank: name for rank, name in enumerate(df1.columns, 1)})

In [7]: df3.columns = range(1, 1 + df3.shape[1])

In [8]: df3
Out[8]: 
   1  2  3  4  5
0  B  A  C  E  D
1  A  E  D  C  B
2  E  B  C  D  A
3  B  C  D  E  A

又一种方式。

In [6]: ranks = df.rank(axis=1).astype(int)-1
In [7]: new_values = df.columns.values.take(ranks)

In [8]: pd.DataFrame(new_values)
Out[8]: 
   0  1  2  3  4
0  B  A  C  E  D
1  A  E  D  C  B
2  E  B  C  D  A
3  B  C  D  E  A

答案 2 :(得分:0)

使用stackreset_indexpivot

df.rank(1).astype(int).stack().reset_index() \
  .pivot('level_0', 0, 'level_1').rename_axis(None)

https://www.ag-grid.com/best-react-data-grid/index.php

<强> 时序

enter image description here