web-dev-qa-db-ja.com

Pandas groupby nlargest sum

Pandas=)でgroupbynlargest、およびsum関数を一緒に使用しようとしていますが、動作させるのに問題があります。

_State    County    Population
Alabama  a         100
Alabama  b         50
Alabama  c         40
Alabama  d         5
Alabama  e         1
...
Wyoming  a.51      180
Wyoming  b.51      150
Wyoming  c.51      56
Wyoming  d.51      5
_

groupbyを使用して州ごとに選択してから、人口ごとに上位2つの郡を取得します。次に、上位2郡の人口のみを使用して、その州の合計を取得します。

最後に、州と人口(その上位2郡)を含むリストを作成します。

groupbynlargestを動作させることはできますが、nlargest(2)の合計を取得するのは困難です。

私が今持っている行は単純です:df.groupby('State')['Population'].nlargest(2)

10
user7102752

applyを実行した後、groupbyを使用できます。

_df.groupby('State')['Population'].apply(lambda grp: grp.nlargest(2).sum())
_

あなたが抱えているこの問題は、df.groupby('State')['Population'].nlargest(2)がDataFrameを返すため、グループレベルの操作ができなくなることだと思います。一般に、グループ内で複数の操作を実行する場合は、apply/aggを使用する必要があります。

結果の出力:

_State
Alabama    150
Wyoming    330
_

[〜#〜] edit [〜#〜]

@cᴏʟᴅsᴘᴇᴇᴅが示唆する、ややクリーンなアプローチ:

_df.groupby('State')['Population'].nlargest(2).sum(level=0)
_

ただし、大きなDataFrameでapplyを使用するよりも若干遅くなります。

次のセットアップを使用します。

_import numpy as np
import pandas as pd
from string import ascii_letters

n = 10**6
df = pd.DataFrame({'A': np.random.choice(list(ascii_letters), size=n),
                   'B': np.random.randint(10**7, size=n)})
_

次のタイミングを取得します。

_In [3]: %timeit df.groupby('A')['B'].apply(lambda grp: grp.nlargest(2).sum())
103 ms ± 1.08 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [4]: %timeit df.groupby('A')['B'].nlargest(2).sum(level=0)
147 ms ± 3.38 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
_

levelsum kwargが内部で2番目のgroupbyを実行すると、パフォーマンスが低下する可能性があります。

23
root

aggを使用すると、グループ化ロジックは次のようになります。

df.groupby('State').agg({'Population': {lambda x: x.nlargest(2).sum() }})

これにより、別のデータフレームオブジェクトが作成されます。最も人口の多い州などを見つけるためにクエリすることができます.

           Population
State
Alabama    150
Wyoming    330
4
aquaraga