web-dev-qa-db-ja.com

パンダDataFrameでcolumnの値が最大となる行を見つける

特定の列の値が最大である行を見つけるにはどうすればよいですか?

df.max()は各列の最大値を教えてくれます。対応する行を取得する方法はわかりません。

175
lazy1

あなたはargmax()idxmax)関数と呼ぶだけでいいのです。それは簡単です:

>>> import pandas
>>> import numpy as np
>>> df = pandas.DataFrame(np.random.randn(5,3),columns=['A','B','C'])
>>> df
          A         B         C
0  1.232853 -1.979459 -0.573626
1  0.140767  0.394940  1.068890
2  0.742023  1.343977 -0.579745
3  2.125299 -0.649328 -0.211692
4 -0.187253  1.908618 -1.862934
>>> df['A'].argmax()
3
>>> df['B'].argmax()
4
>>> df['C'].argmax()
1

この関数はPandas APIでidxmaxという名前に更新されましたが、Pandas 0.16の時点ではargmaxがまだ存在し、同じ機能を実行します(ただしidxmaxより実行速度が遅いようです)。

numpy.argmax(df['A'])のようにnumpy.argmaxを使用することもできます。これは、2つのpandas関数のいずれかと同じことを提供し、少なくとも概観的観察ではidxmaxと同じくらい高速に表示されます。

以前は(コメントに記載されているように)argmaxは別の関数として存在し、その行位置のインデックス内で整数位置を提供するように見えました。最大要素たとえば、行 'a'から 'e'のように、インデックスラベルとして文字列値がある場合、最大値が行4(行 'd'ではなく)にあることを知りたいと思うかもしれません。ただし、パンダ0.16では、上記のすべてのメソッドは、問題の行のIndexからラベルのみを提供します。 Index内のそのラベルを手動で取得する必要があります(重複する行ラベルが許可されるようになったので、注意が必要です)。

一般的に、3つのアプローチ(まだ存在するidxmaxargmax、およびnumpy.argmax)すべてに対してidxmaxのような振る舞いをすることは悪いことだと思います。特に重複する行ラベルが一般的なアプリケーションでは、インデックス内のその位置のラベルを希望するよりも、さらに一般的なことがよくあります。

たとえば、行ラベルが重複しているおもちゃDataFrameを考えてみます。

In [19]: dfrm
Out[19]: 
          A         B         C
a  0.143693  0.653810  0.586007
b  0.623582  0.312903  0.919076
c  0.165438  0.889809  0.000967
d  0.308245  0.787776  0.571195
e  0.870068  0.935626  0.606911
f  0.037602  0.855193  0.728495
g  0.605366  0.338105  0.696460
h  0.000000  0.090814  0.963927
i  0.688343  0.188468  0.352213
i  0.879000  0.105039  0.900260

In [20]: dfrm['A'].idxmax()
Out[20]: 'i'

In [21]: dfrm.ix[dfrm['A'].idxmax()]
Out[21]: 
          A         B         C
i  0.688343  0.188468  0.352213
i  0.879000  0.105039  0.900260

そのため、ここでidxmaxを単純に使用するだけでは不十分ですが、古い形式のargmaxでは、最大行の位置の位置を正しく指定できます(この場合、ポジション9)。

これは、動的に型付けされた言語における厄介な種類のバグが発生しやすい動作の1つで、このようなことを非常に不幸なものにしています。システムコードを書いていて、結合前に正しくクリーニングされていない一部のデータセットでシステムが突然使用されるようになった場合は、重複行ラベル、特に金融資産のCUSIPまたはSEDOL識別子のような文字列ラベルを使用するのは非常に簡単です。型システムを使用して手助けするのは簡単ではありません。また、予期せぬデータの欠落に遭遇しない限り、インデックスに一意性を強制することはできません。

それで、あなたはあなたのユニットテストがすべてをカバーすることを願って残されています(彼らはテストを書かなかった、あるいはおそらく誰もテストを書いていないでしょう) - そうでなければ(ほとんどの場合)実行時にエラーが発生した場合は、結果を出力していたデータベースから何時間もの作業を削除し、手動で問題を再現しようとするIPythonの壁にぶつかり、最終的にidxmaxが可能だからです。 のみ最大行のラベルを報告し、それからがっかりしている標準の関数では自動的に最大行の位置を取得し、自分でバグのある実装を作成し、コードを編集し、あなたが遭遇しないことを祈るもう一度問題。

196
ely

idxmaxを試すこともできます。

In [5]: df = pandas.DataFrame(np.random.randn(10,3),columns=['A','B','C'])

In [6]: df
Out[6]: 
          A         B         C
0  2.001289  0.482561  1.579985
1 -0.991646 -0.387835  1.320236
2  0.143826 -1.096889  1.486508
3 -0.193056 -0.499020  1.536540
4 -2.083647 -3.074591  0.175772
5 -0.186138 -1.949731  0.287432
6 -0.480790 -1.771560 -0.930234
7  0.227383 -0.278253  2.102004
8 -0.002592  1.434192 -1.624915
9  0.404911 -2.167599 -0.452900

In [7]: df.idxmax()
Out[7]: 
A    0
B    8
C    7

例えば.

In [8]: df.loc[df['A'].idxmax()]
Out[8]: 
A    2.001289
B    0.482561
C    1.579985
67
Wes McKinney

最大値をとる行が複数ある場合、上記の両方の回答は1つのインデックスのみを返します。すべての行が必要な場合は、関数がないようです。しかし、それは難しいことではありません。以下はシリーズの例です。 DataFrameについても同じことができます。

In [1]: from pandas import Series, DataFrame

In [2]: s=Series([2,4,4,3],index=['a','b','c','d'])

In [3]: s.idxmax()
Out[3]: 'b'

In [4]: s[s==s.max()]
Out[4]: 
b    4
c    4
dtype: int64
20
mxia
df.iloc[df['columnX'].argmax()]

argmax()はcolumnXの最大値に対応するインデックスを提供します。 ilocを使用して、このインデックスのDataFrame dfの行を取得できます。

8
Nafeez Quraishi
mx.iloc[0].idxmax()

この1行のコードは、データフレーム内の行から最大値を見つける方法を示します。ここで、 'mx'はデータフレームで、iloc [0]は0番目のインデックスを示します。

1
Manjula Devi

直接的な ".argmax()"ソリューションは私にはうまくいきません。

@ ely によって提供される前の例

>>> import pandas
>>> import numpy as np
>>> df = pandas.DataFrame(np.random.randn(5,3),columns=['A','B','C'])
>>> df
      A         B         C
0  1.232853 -1.979459 -0.573626
1  0.140767  0.394940  1.068890
2  0.742023  1.343977 -0.579745
3  2.125299 -0.649328 -0.211692
4 -0.187253  1.908618 -1.862934
>>> df['A'].argmax()
3
>>> df['B'].argmax()
4
>>> df['C'].argmax()
1

次のメッセージを返します。

FutureWarning: 'argmax' is deprecated, use 'idxmax' instead. The behavior of 'argmax' 
will be corrected to return the positional maximum in the future.
Use 'series.values.argmax' to get the position of the maximum now.

だから私の解決策は次のとおりです。

df['A'].values.argmax()
1
AntoineP

ここに彼ら自身のために話すいくつかの役に立つ例があります。

np.random.seed(0)                                                                                                      
df = pd.DataFrame(
    [[1, 2, 9], [7, 5, 6], [4, 8, 3]], columns=list('ABC'), index=list('xyz'))                           

df                                                                                                                     

   A  B  C
x  1  2  9
y  7  5  6
z  4  8  3

列あたりの最大行数のインデックス:

df.idxmax()                                                                                                            

A    y
B    z
C    x
dtype: object

# for a specific column, use
df['A'].idxmax()                                                                                                      
# 'y' 

1行あたりの最大列インデックス

df.idxmax(axis=1)                                                                                                     

x    C
y    A
z    B
dtype: object

列あたりの最大行数の整数位置:

df.idxmax().map(df.index.get_loc)                                                                                     

A    1
B    2
C    0
dtype: int64


# For a specific column, pass the label to `Index.get_loc`
df.index.get_loc(df['A'].idxmax())                                                                                   
# 1

df['A'].to_numpy().argmax()                                                                                           
# 1


将来のバージョンでは、 Series.argmax が最大の整数位置を返すためのデファクトになるでしょう。今のところ、それはSeries.idxmaxと同じ振る舞いをして、FutureWarningを返します。今のところ、df['A'].to_numpy().argmax()

行あたりの最大列の整数位置

df.idxmax(axis=1).map(df.columns.get_loc)                                                                             

x    2
y    0
z    1
dtype: int64

# For a specific row,
df.columns.get_loc(df.loc['x'].idxmax())                                                                              
# 2
0
cs95

DataFrameのidmaxは最大値を持つ行のラベルインデックスを返し、argmaxの動作はpandasのバージョンによって異なります(現在は警告が返されます)。 位置インデックスを使用したい場合は、次のようにします。

max_row = df['A'].values.argmax()

またはnp max_row = np.argmax(df ['A']。values)としてnumpyをインポートする

np.argmax(df['A'])を使用した場合、df['A'].argmax()と同じ動作をすることに注意してください。

0
Jonathan