私はpandas DataFrameを持っています。これは、ユーザーセッション中の「クリック」に関してオンラインアクティビティの詳細を示します。50,000ものユニークユーザーがいて、データフレームには約150万のサンプルがあります。明らかにほとんどのユーザー複数のレコードがあります。
4つの列は、一意のユーザーID、ユーザーがサービスを開始した日付「登録」、ユーザーがサービスを使用した日付「セッション」、クリックの総数です。
データフレームの構成は次のとおりです。
_User_ID Registration Session clicks
2349876 2012-02-22 2014-04-24 2
1987293 2011-02-01 2013-05-03 1
2234214 2012-07-22 2014-01-22 7
9874452 2010-12-22 2014-08-22 2
...
_
(0から始まるインデックスもありますが、_User_ID
_をインデックスとして設定することもできます。)
登録日からのユーザーの合計クリック数を集計したい。データフレーム(またはpandas Seriesオブジェクト)は、User_IDおよび "Total_Number_Clicks"をリストします。
_User_ID Total_Clicks
2349876 722
1987293 341
2234214 220
9874452 1405
...
_
パンダでこれをどのように行うのですか?これは.agg()
によって行われますか?各_User_ID
_は個別に合計する必要があります。
150万件のレコードがあるので、これはスケールできますか?
IIUCで使用できる groupby
、 sum
および reset_index
:
print df
User_ID Registration Session clicks
0 2349876 2012-02-22 2014-04-24 2
1 1987293 2011-02-01 2013-05-03 1
2 2234214 2012-07-22 2014-01-22 7
3 9874452 2010-12-22 2014-08-22 2
print df.groupby('User_ID')['clicks'].sum().reset_index()
User_ID clicks
0 1987293 1
1 2234214 7
2 2349876 2
3 9874452 2
最初の列の場合User_ID
はindex
です:
print df
Registration Session clicks
User_ID
2349876 2012-02-22 2014-04-24 2
1987293 2011-02-01 2013-05-03 1
2234214 2012-07-22 2014-01-22 7
9874452 2010-12-22 2014-08-22 2
print df.groupby(level=0)['clicks'].sum().reset_index()
User_ID clicks
0 1987293 1
1 2234214 7
2 2349876 2
3 9874452 2
または:
print df.groupby(df.index)['clicks'].sum().reset_index()
User_ID clicks
0 1987293 1
1 2234214 7
2 2349876 2
3 9874452 2
編集:
Alexander が指摘されているため、groupby
の日付がSession
の日付よりも小さい場合、Registration
の前にフィルターデータが必要ですUser_ID
:
print df
User_ID Registration Session clicks
0 2349876 2012-02-22 2014-04-24 2
1 1987293 2011-02-01 2013-05-03 1
2 2234214 2012-07-22 2014-01-22 7
3 9874452 2010-12-22 2014-08-22 2
print df[df.Session >= df.Registration].groupby('User_ID')['clicks'].sum().reset_index()
User_ID clicks
0 1987293 1
1 2234214 7
2 2349876 2
3 9874452 2
より良いサンプルのために3行のデータを変更します。
print df
Registration Session clicks
User_ID
2349876 2012-02-22 2014-04-24 2
1987293 2011-02-01 2013-05-03 1
2234214 2012-07-22 2012-01-22 7
9874452 2010-12-22 2014-08-22 2
print df.Session >= df.Registration
User_ID
2349876 True
1987293 True
2234214 False
9874452 True
dtype: bool
print df[df.Session >= df.Registration]
Registration Session clicks
User_ID
2349876 2012-02-22 2014-04-24 2
1987293 2011-02-01 2013-05-03 1
9874452 2010-12-22 2014-08-22 2
df1 = df[df.Session >= df.Registration]
print df1.groupby(df1.index)['clicks'].sum().reset_index()
User_ID clicks
0 1987293 1
1 2349876 2
2 9874452 2
最初に、登録日より前の登録日をフィルタリングし、次にUser_IDと合計でグループ化します。
gb = (df[df.Session >= df.Registration]
.groupby('User_ID')
.clicks.agg({'Total_Clicks': np.sum}))
>>> gb
Total_Clicks
User_ID
1987293 1
2234214 7
2349876 2
9874452 2
あなたが言及したユースケースでは、これはスケーラブルだと思います。もちろん、それは常に利用可能なメモリに依存します。
データフレーム名がdfであるとすると、次のようにします
df.groupby(['User_ID']).sum()[['User_ID','clicks']]