numpy 获取pandas列中的第一个和第二个最高值

cnwbcb6i  于 2023-04-06  发布在  其他
关注(0)|答案(8)|浏览(253)

我正在使用pandas分析一些选举结果。我有一个DF,Results,其中每个选区有一行,列代表各个政党的选票(超过100个):

In[60]: Results.columns
Out[60]: 
Index(['Constituency', 'Region', 'Country', 'ID', 'Type', 'Electorate',
       'Total', 'Unnamed: 9', '30-50', 'Above',
       ...
       'WP', 'WRP', 'WVPTFP', 'Yorks', 'Young', 'Zeb', 'Party', 'Votes',
       'Share', 'Turnout'],
      dtype='object', length=147)

所以...

In[63]: Results.head()
Out[63]: 
                         Constituency    Region   Country         ID    Type  \
PAID                                                                           
1                            Aberavon     Wales     Wales  W07000049  County   
2                           Aberconwy     Wales     Wales  W07000058  County   
3                      Aberdeen North  Scotland  Scotland  S14000001   Burgh   
4                      Aberdeen South  Scotland  Scotland  S14000002   Burgh   
5     Aberdeenshire West & Kincardine  Scotland  Scotland  S14000058  County   

      Electorate  Total  Unnamed: 9  30-50  Above    ...     WP  WRP  WVPTFP  \
PAID                                                 ...                       
1          49821  31523         NaN    NaN    NaN    ...    NaN  NaN     NaN   
2          45525  30148         NaN    NaN    NaN    ...    NaN  NaN     NaN   
3          67745  43936         NaN    NaN    NaN    ...    NaN  NaN     NaN   
4          68056  48551         NaN    NaN    NaN    ...    NaN  NaN     NaN   
5          73445  55196         NaN    NaN    NaN    ...    NaN  NaN     NaN   

      Yorks  Young  Zeb  Party  Votes     Share   Turnout  
PAID                                                       
1       NaN    NaN  NaN    Lab  15416  0.489040  0.632725  
2       NaN    NaN  NaN    Con  12513  0.415052  0.662230  
3       NaN    NaN  NaN    SNP  24793  0.564298  0.648550  
4       NaN    NaN  NaN    SNP  20221  0.416490  0.713398  
5       NaN    NaN  NaN    SNP  22949  0.415773  0.751528  

[5 rows x 147 columns]

每个政党的每个选区的结果在Results.ix[:, 'Unnamed: 9': 'Zeb']列中给出
我可以找到获胜的政党(即获得最高票数的政党)以及它所获得的票数:

RawResults = Results.ix[:, 'Unnamed: 9': 'Zeb']
Results['Party'] = RawResults.idxmax(axis=1)
Results['Votes'] = RawResults.max(axis=1).astype(int)

但是,我还需要知道第二名政党获得了多少选票(最好是它的索引/名称),那么在panda中有没有办法在一组列中为每行返回 * 第二 * 最高值/索引呢?

7ajki6be

7ajki6be1#

要获取列的最大值,可以使用nlargest()

df['High'].nlargest(2)

上面将给予列High的2最高值。
您也可以使用nsmallest()来获取最低值。

ffscu2ro

ffscu2ro2#

以下是NumPy的解决方案:

In [120]: df
Out[120]:
          a         b         c         d         e         f         g         h
0  1.334444  0.322029  0.302296 -0.841236 -0.360488 -0.860188 -0.157942  1.522082
1  2.056572  0.991643  0.160067 -0.066473  0.235132  0.533202  1.282371 -2.050731
2  0.955586 -0.966734  0.055210 -0.993924 -0.553841  0.173793 -0.534548 -1.796006
3  1.201001  1.067291 -0.562357 -0.794284 -0.554820 -0.011836  0.519928  0.514669
4 -0.243972 -0.048144  0.498007  0.862016  1.284717 -0.886455 -0.757603  0.541992
5  0.739435 -0.767399  1.574173  1.197063 -1.147961 -0.903858  0.011073 -1.404868
6 -1.258282 -0.049719  0.400063  0.611456  0.443289 -1.110945  1.352029  0.215460
7  0.029121 -0.771431 -0.285119 -0.018216  0.408425 -1.458476 -1.363583  0.155134
8  1.427226 -1.005345  0.208665 -0.674917  0.287929 -1.259707  0.220420 -1.087245
9  0.452589  0.214592 -1.875423  0.487496  2.411265  0.062324 -0.327891  0.256577

In [121]: np.sort(df.values)[:,-2:]
Out[121]:
array([[ 1.33444404,  1.52208164],
       [ 1.28237078,  2.05657214],
       [ 0.17379254,  0.95558613],
       [ 1.06729107,  1.20100071],
       [ 0.86201603,  1.28471676],
       [ 1.19706331,  1.57417327],
       [ 0.61145573,  1.35202868],
       [ 0.15513379,  0.40842477],
       [ 0.28792928,  1.42722604],
       [ 0.48749578,  2.41126532]])

或者作为pandas数据框:

In [122]: pd.DataFrame(np.sort(df.values)[:,-2:], columns=['2nd-largest','largest'])
Out[122]:
   2nd-largest   largest
0     1.334444  1.522082
1     1.282371  2.056572
2     0.173793  0.955586
3     1.067291  1.201001
4     0.862016  1.284717
5     1.197063  1.574173
6     0.611456  1.352029
7     0.155134  0.408425
8     0.287929  1.427226
9     0.487496  2.411265

或来自@Divakar的更快解决方案:

In [6]: df
Out[6]:
          a         b         c         d         e         f         g         h
0  0.649517 -0.223116  0.264734 -1.121666  0.151591 -1.335756 -0.155459 -2.500680
1  0.172981  1.233523  0.220378  1.188080 -0.289469 -0.039150  1.476852  0.736908
2 -1.904024  0.109314  0.045741 -0.341214 -0.332267 -1.363889  0.177705 -0.892018
3 -2.606532 -0.483314  0.054624  0.979734  0.205173  0.350247 -1.088776  1.501327
4  1.627655 -1.261631  0.589899 -0.660119  0.742390 -1.088103  0.228557  0.714746
5  0.423972 -0.506975 -0.783718 -2.044002 -0.692734  0.980399  1.007460  0.161516
6 -0.777123 -0.838311 -1.116104 -0.433797  0.599724 -0.884832 -0.086431 -0.738298
7  1.131621  1.218199  0.645709  0.066216 -0.265023  0.606963 -0.194694  0.463576
8  0.421164  0.626731 -0.547738  0.989820 -1.383061 -0.060413 -1.342769 -0.777907
9 -1.152690  0.696714 -0.155727 -0.991975 -0.806530  1.454522  0.788688  0.409516

In [7]: a = df.values

In [8]: a[np.arange(len(df))[:,None],np.argpartition(-a,np.arange(2),axis=1)[:,:2]]
Out[8]:
array([[ 0.64951665,  0.26473378],
       [ 1.47685226,  1.23352348],
       [ 0.17770473,  0.10931398],
       [ 1.50132666,  0.97973383],
       [ 1.62765464,  0.74238959],
       [ 1.00745981,  0.98039898],
       [ 0.5997243 , -0.0864306 ],
       [ 1.21819904,  1.13162068],
       [ 0.98982033,  0.62673128],
       [ 1.45452173,  0.78868785]])
4jb9z9bj

4jb9z9bj3#

这里是一个有趣的方法.如果我们用最小值替换最大值并计算.虽然这是一个快速的黑客和,不建议!

first_highest_value_index = df.idxmax()
second_highest_value_index = df.replace(df.max(),df(min)).idxmax()

first_highest_value = df[first_highest_value_index]
second_highest_value = df[second_highest_value_index]
tct7dpnv

tct7dpnv4#

你可以对结果进行排序,这样第一行就包含了最大值,然后你可以简单地使用索引来获得前n个位置。

RawResults = Results.ix[:, 'Unnamed: 9': 'Zeb'].sort_values(by='votes', ascending=False)
RawResults.iloc[0, :] # First place
RawResults.iloc[1, :] # Second place
RawResults.iloc[n, :] # nth place
aor9mmx1

aor9mmx15#

下面是使用nlargest函数的解决方案:

>>> df
    a   b   c
 0  4  20   2
 1  5  10   2
 2  3  40   5
 3  1  50  10
 4  2  30  15
>>> def give_largest(col,n):
...     largest = col.nlargest(n).reset_index(drop = True)
...     data = [x for x in largest]
...     index = [f'{i}_largest' for i in range(1,len(largest)+1)]
...     return pd.Series(data,index=index)
...
...
>>> def n_largest(df, axis, n):
...     '''
...     Function to return the n-largest value of each
...     column/row of the input DataFrame.
...     '''
...     return df.apply(give_largest, axis = axis, n = n)
...
>>> n_largest(df,axis = 1, n = 2)
   1_largest  2_largest
0         20          4
1         10          5
2         40          5
3         50         10
4         30         15
>>> n_largest(df,axis = 0, n = 2)
                  a           b           c     
1_largest         5          50           15
2_largest         4          40           10
fkvaft9z

fkvaft9z6#

import numpy as np
import pandas as pd

df = pd.DataFrame({
    'a': [4, 5, 3, 1, 2],
    'b': [20, 10, 40, 50, 30],
    'c': [25, 20, 5, 15, 10]
})
def second_largest(df):
    
    return (df.nlargest(2).min())



print(df.apply(second_largest))
a     4
b    40
c    20
dtype: int64
hxzsmxv2

hxzsmxv27#

df
           a           b           c            d           e           f           g          h
0   1.334444    0.322029    0.302296    -0.841236   -0.360488   -0.860188   -0.157942   1.522082
1   2.056572    0.991643    0.160067    -0.066473   0.235132    0.533202    1.282371    -2.050731
2   0.955586    -0.966734   0.055210    -0.993924   -0.553841   0.173793    -0.534548   -1.796006
3   1.201001    1.067291    -0.562357   -0.794284   -0.554820   -0.011836   0.519928    0.514669
4   -0.243972   -0.048144   0.498007    0.862016    1.284717    -0.886455   -0.757603   0.541992
5   0.739435    -0.767399   1.574173    1.197063    -1.147961   -0.903858   0.011073    -1.404868
6   -1.258282   -0.049719   0.400063    0.611456    0.443289    -1.110945   1.352029    0.215460
7   0.029121    -0.771431   -0.285119   -0.018216   0.408425    -1.458476   -1.363583   0.155134
8   1.427226    -1.005345   0.208665    -0.674917   0.287929    -1.259707   0.220420    -1.087245
9   0.452589    0.214592    -1.875423   0.487496    2.411265    0.062324    -0.327891   0.256577

转置并在for循环中使用nlargest来获得每行的结果:

df1=df.T
results=list()
for col in df1.columns: results.append(df1[col].nlargest(len(df.columns))

results var是pandas对象的列表,其中列表中的第一项将是df的第一行,按降序排序,依此类推。由于列表中的每个项都是pandas对象,它携带df的列作为索引(它被转置),因此您将获得排序的每行的值和df的列名

results
[h    1.522082
 a    1.334444
 b    0.322029
 c    0.302296
 g   -0.157942
 e   -0.360488
 d   -0.841236
 f   -0.860188
 Name: 0, dtype: float64,
 a    2.056572
 g    1.282371
 b    0.991643
 f    0.533202
 e    0.235132
 c    0.160067
 d   -0.066473
 h   -2.050731
 Name: 1, dtype: float64,
....
nwlqm0z1

nwlqm0z18#

由于排序应用于每一列,索引标签无论如何都会被删除。我们可以使用numpy来实现这一点:

a=np.random.random([10,4])
a
Out[10]: 
array([[0.11965879, 0.73168303, 0.18521419, 0.13992709],
       [0.8758143 , 0.13136781, 0.22071495, 0.9369399 ],
       [0.9190763 , 0.14320333, 0.66614619, 0.60688266],
       [0.91973194, 0.25297882, 0.02097999, 0.93834247],
       [0.70570349, 0.92229061, 0.64739799, 0.21614292],
       [0.70386848, 0.58542997, 0.78042638, 0.65968369],
       [0.37626386, 0.32668468, 0.42756616, 0.00938118],
       [0.85126718, 0.76305889, 0.03047206, 0.4874788 ],
       [0.88951106, 0.65035676, 0.98210505, 0.35605393],
       [0.96369325, 0.79311159, 0.81995022, 0.10588205]])
np.sort(a, axis=0)

我们有输出:

array([[0.11965879, 0.13136781, 0.02097999, 0.00938118],
       [0.37626386, 0.14320333, 0.03047206, 0.10588205],
       [0.70386848, 0.25297882, 0.18521419, 0.13992709],
       [0.70570349, 0.32668468, 0.22071495, 0.21614292],
       [0.85126718, 0.58542997, 0.42756616, 0.35605393],
       [0.8758143 , 0.65035676, 0.64739799, 0.4874788 ],
       [0.88951106, 0.73168303, 0.66614619, 0.60688266],
       [0.9190763 , 0.76305889, 0.78042638, 0.65968369],
       [0.91973194, 0.79311159, 0.81995022, 0.9369399 ],
       [0.96369325, 0.92229061, 0.98210505, 0.93834247]])

这里每一列都是排序的,你可以对矩阵进行切片以获得所需的值。

相关问题