2017-06-02 1 views
2

私は2つの異なるグループを結合し、それらのうちの1つをフィルタリングする必要があるデータフレームを持っています。パンダは2つのグループを結合し、グループをフィルタリングしてマージします。

ID  EVENT  SUCCESS 
1  PUT   Y 
2  POST   Y 
2  PUT   N 
1  DELETE  Y 

この表は、どのようにデータを表示したいかを示しています。まず、「イベント」のカウントをグループ化し、第二は、ID

ID PUT POST DELETE SUCCESS 
1 1  0  1  2 
2 1  1  0  1 

あたりの成功の量(「Y」)をカウントすることで、私はいくつかのテクニックを試してみたし、私が見つけたクローゼットは、2つの別々の方法でこれは「イベント」のために、以下のことはフィルタを使用して成功するために

ID PUT POST DELETE 
1 1  0  1  
2 1  1  0  

をカウントし、私は私かどうか知らない生み出す以下

group_df = df.groupby(['ID', 'EVENT']) count_group_df = group_df.size().unstack()

をもたらします「ID」私は何とかこれらを結合する必要が

df_success = df.loc[df['SUCCESS'] == 'Y', ['ID', 'SUCCESS']] 
count_group_df_2 = df_success.groupby(['ID', 'SUCCESS']) 


ID SUCCESS 
1  2 
2  1 

上の最初のセットには、このに参加することができますか?

また、「EVENT」の2つ、たとえばPUTとPOSTの数を1つの列にマージしたいと思います。

答えて

1

使用concatのためにそれらを一緒にマージ:

df1 = df.groupby(['ID', 'EVENT']).size().unstack(fill_value=0) 
df_success = (df['SUCCESS'] == 'Y').groupby(df['ID']).sum().astype(int) 
df = pd.concat([df1, df_success],axis=1) 
print (df) 
    DELETE POST PUT SUCCESS 
ID        
1  1  0 1  2 
2  0  1 1  1 

value_countsと別の解決策:

df1 = df.groupby(['ID', 'EVENT']).size().unstack(fill_value=0) 
df_success = df.loc[df['SUCCESS'] == 'Y', 'ID'].value_counts().rename('SUCCESS') 
df = pd.concat([df1, df_success],axis=1) 
print (df) 
    DELETE POST PUT SUCCESS 
ID        
1  1  0 1  2 
2  0  1 1  1 

最終列に可能な変換の指数であり、列を削除はreset_index + rename_axisIDに名前を付ける:

df = df.reset_index().rename_axis(None, axis=1) 
print (df) 
    ID DELETE POST PUT SUCCESS 
0 1  1  0 1  2 
1 2  0  1 1  1 
1

pandas

pd.get_dummies(df.EVENT) \ 
    .assign(SUCCESS=df.SUCCESS.eq('Y').astype(int)) \ 
    .groupby(df.ID).sum().reset_index() 

    ID DELETE POST PUT SUCCESS 
0 1  1  0 1  2 
1 2  0  1 1  1 

numpypandas

f, u = pd.factorize(df.EVENT.values) 
n = u.size 
d = np.eye(n)[f] 
s = (df.SUCCESS.values == 'Y').astype(int) 
d1 = pd.DataFrame(
    np.column_stack([d, s]), 
    df.index, np.append(u, 'SUCCESS') 
) 
d1.groupby(df.ID).sum().reset_index() 

    ID DELETE POST PUT SUCCESS 
0 1  1  0 1  2 
1 2  0  1 1  1 

タイミング
小さなデータ

%%timeit 
f, u = pd.factorize(df.EVENT.values) 
n = u.size 
d = np.eye(n)[f] 
s = (df.SUCCESS.values == 'Y').astype(int) 
d1 = pd.DataFrame(
    np.column_stack([d, s]), 
    df.index, np.append(u, 'SUCCESS') 
) 
d1.groupby(df.ID).sum().reset_index() 
1000 loops, best of 3: 1.32 ms per loop 

%%timeit 
df1 = df.groupby(['ID', 'EVENT']).size().unstack(fill_value=0) 
df_success = (df['SUCCESS'] == 'Y').groupby(df['ID']).sum().astype(int) 
pd.concat([df1, df_success],axis=1).reset_index() 
100 loops, best of 3: 3.3 ms per loop 

%%timeit 
df1 = df.groupby(['ID', 'EVENT']).size().unstack(fill_value=0) 
df_success = df.loc[df['SUCCESS'] == 'Y', 'ID'].value_counts().rename('SUCCESS') 
pd.concat([df1, df_success],axis=1).reset_index() 
100 loops, best of 3: 3.28 ms per loop 

%timeit pd.get_dummies(df.EVENT).assign(SUCCESS=df.SUCCESS.eq('Y').astype(int)).groupby(df.ID).sum().reset_index() 
100 loops, best of 3: 2.62 ms per loop 

大規模データ

df = pd.DataFrame(dict(
     ID=np.random.randint(100, size=100000), 
     EVENT=np.random.choice('PUT POST DELETE'.split(), size=100000), 
     SUCCESS=np.random.choice(list('YN'), size=100000) 
    )) 

%%timeit 
f, u = pd.factorize(df.EVENT.values) 
n = u.size 
d = np.eye(n)[f] 
s = (df.SUCCESS.values == 'Y').astype(int) 
d1 = pd.DataFrame(
    np.column_stack([d, s]), 
    df.index, np.append(u, 'SUCCESS') 
) 
d1.groupby(df.ID).sum().reset_index() 
100 loops, best of 3: 10.8 ms per loop 

%%timeit 
df1 = df.groupby(['ID', 'EVENT']).size().unstack(fill_value=0) 
df_success = (df['SUCCESS'] == 'Y').groupby(df['ID']).sum().astype(int) 
pd.concat([df1, df_success],axis=1).reset_index() 
100 loops, best of 3: 17.7 ms per loop 

%%timeit 
df1 = df.groupby(['ID', 'EVENT']).size().unstack(fill_value=0) 
df_success = df.loc[df['SUCCESS'] == 'Y', 'ID'].value_counts().rename('SUCCESS') 
pd.concat([df1, df_success],axis=1).reset_index() 
100 loops, best of 3: 17.4 ms per loop 

%timeit pd.get_dummies(df.EVENT).assign(SUCCESS=df.SUCCESS.eq('Y').astype(int)).groupby(df.ID).sum().reset_index() 
100 loops, best of 3: 16.8 ms per loop 
関連する問題