web-dev-qa-db-ja.com

pandas集計の条件付き合計

最近、Rからpythonに切り替えたところ、Rのdata.tableを使用するのではなく、データフレームに再び慣れるのに問題がありました。私が抱えていた問題は、文字列のリストを取得し、値を確認してから、その文字列の数を合計します-ユーザーごとに分類します。したがって、このデータを取得したいと思います。

   A_id       B    C
1:   a1    "up"  100
2:   a2  "down"  102
3:   a3    "up"  100
3:   a3    "up"  250
4:   a4  "left"  100
5:   a5 "right"  102

そして戻る:

   A_id_grouped   sum_up   sum_down  ...  over_200_up
1:           a1        1          0  ...            0
2:           a2        0          1                 0
3:           a3        2          0  ...            1
4:           a4        0          0                 0
5:           a5        0          0  ...            0

Rコードでそれを行う前に(data.tableを使用して)

>DT[ ,list(A_id_grouped, sum_up = sum(B == "up"),
+  sum_down = sum(B == "down"), 
+  ...,
+  over_200_up = sum(up == "up" & < 200), by=list(A)];

しかし、Pythonでの最近の試みはすべて失敗しました:

DT.agg({"D": [np.sum(DT[DT["B"]=="up"]),np.sum(DT[DT["B"]=="up"])], ...
    "C": np.sum(DT[(DT["B"]=="up") & (DT["C"]>200)])
    })

前もって感謝します!簡単な質問のようですが、どこにも見つかりませんでした。

19
stites

Unutbuの答えを補完するために、groupbyオブジェクトでapplyを使用するアプローチを次に示します。

>>> df.groupby('A_id').apply(lambda x: pd.Series(dict(
    sum_up=(x.B == 'up').sum(),
    sum_down=(x.B == 'down').sum(),
    over_200_up=((x.B == 'up') & (x.C > 200)).sum()
)))
      over_200_up  sum_down  sum_up
A_id                               
a1              0         0       1
a2              0         1       0
a3              1         0       2
a4              0         0       0
a5              0         0       0
19
Garrett

より良い方法があるかもしれません。私はパンダにかなり慣れていませんが、これは機能します:

import pandas as pd
import numpy as np

df = pd.DataFrame({'A_id':'a1 a2 a3 a3 a4 a5'.split(),
                   'B': 'up down up up left right'.split(),
                   'C': [100, 102, 100, 250, 100, 102]})

df['D'] = (df['B']=='up') & (df['C'] > 200)
grouped = df.groupby(['A_id'])

def sum_up(grp):
    return np.sum(grp=='up')
def sum_down(grp):
    return np.sum(grp=='down')
def over_200_up(grp):
    return np.sum(grp)

result = grouped.agg({'B': [sum_up, sum_down],
                      'D': [over_200_up]})
result.columns = [col[1] for col in result.columns]
print(result)

収量

      sum_up  sum_down  over_200_up
A_id                               
a1         1         0            0
a2         0         1            0
a3         2         0            1
a4         0         0            0
a5         0         0            0
9
unutbu