2017-05-11 13 views
2

上の条件付きフィルターとGROUPBY:、私は次のような構造を持つデータフレーム持っているパンダのデータフレーム

date kind sector 
0 2017-02-01 P A 
1 2017-02-01 P A 
2 2017-02-01 L A 
3 2017-02-01 G A 
4 2017-02-01 P B 
5 2017-02-01 P B 
6 2017-02-01 L B 
7 2017-02-01 T B 
8 2017-02-02 P A 
9 2017-02-02 P A 
10 2017-02-02 L A 
11 2017-02-02 T A 
12 2017-02-02 A B 
13 2017-02-02 P B 
14 2017-02-02 L B 
15 2017-02-02 L B 

をそして、私はルールがkind == Pかのことですフォーマット

date  sector free occupied total 
    2017-02-01 A  2 2   4 
    2017-02-01 B  2 2   4 
    2017-02-02 A  2 2   4 
    2017-02-02 A  3 1   4 

と集約を作成したいですそれ以外は無料で、合計はすべてのエントリの合計です。このカウントを行うための方法はあり

df_p = df[df.kind == 'P'] 
df_np = df[df.kind != 'P'] 
df_t = df_p.groupby(['date', 'sector'], as_index=False).count() 
df_nt = df_np.groupby(['date', 'sector'], as_index=False).count() 
df_nt.rename(columns={'kind':'free'}, inplace=True) 
df_t = pd.concat([df_t, df_nt]) 

:私がして、グループにapplyを使用しようとしましたが、それは仕事didn't:

df.groupby(['date', 'kind']).apply(lambda x: 1 if x == 'P' else 0) 

そして、データフレームを分割してもdidn't仕事を組み合わせることを?

+1

は間違い希望する出力の最後の行ですか? '2017-02-01 A 3 1 4' あなたは' 2017-02-01 A'を繰り返すようです。 – Moondra

+1

タイポが修正されました。 – Ivan

答えて

2

"占有" と "自由" のための2つの新しい変数を作成します。

(所望の出力列の順序を達成するためにここに代わり dictOrderedDictを使用して)
df['occupied'] = (df.kind == "P").astype(int) 
df['free'] = (df.kind != "P").astype(int) 

次に集計:

df_2 = (
    df.groupby(["date","sector"]) 
    .agg(OrderedDict((("free" , np.sum) , ("occupied" , np.sum)))) 
) 

合計列を作成してください:

df_2["total"] = df_2["free"] + df_2["occupied"] 

出力:

enter image description here

0

試してみてください。

df['kind'] = df.kind.apply(lambda x: 'occupied' if x == 'P' else 'free') 
df1 = pd.get_dummies(df.kind).join(df).groupby(['date','sector']).sum().reset_index() 
df1['total'] = df1['occupied']+df1['free']  
df1 

    #   date sector free occupied total 
    # 0 2017-02-01  A  2   2  4 
    # 1 2017-02-01  B  2   2  4 
    # 2 2017-02-02  A  2   2  4 
    # 3 2017-02-02  B  3   1  4 

あなたは基本的にここに何がある:あなたのkind列内の自由と他の占有、すべての最初の代替P。次に、新しくフォーマットされたkindの値をpd.get_dummiesに分類します。その出力はメインのデータフレームに再び結合されます。この時点で、datesectorでグループ化し、それぞれsumとすることができます。最終的にはreset_indexになり、totalの列が計算されます。

こちらがお役に立てば幸いです。

0

ここでこれを行うにワンライナーさ:

#group by date and sector, apply 3 functions to kind to get the sum for free, occupied and total in one go. 
df.groupby(['date','sector'])['kind'].agg({'free':lambda x: sum(x!='P'),'occupied':lambda x: sum(x=='P'), 'total':len}) 
Out[339]: 
        free occupied total 
date  sector      
2017-02-01 A   2   2  4 
      B   2   2  4 
2017-02-02 A   2   2  4 
      B   3   1  4 

、より詳細なアプローチ:

#Transform the kind column to free or occupied only 
df.kind = df.kind.replace('[^P]','free',regex=True).replace('P','occupied') 
#Convert kind from long to wide columns 
df = pd.get_dummies(df,columns=['kind'],prefix='',prefix_sep='') 
#get total 
df['total']=df.free+df.occupied 
#groupby and sum 
df.groupby(['date','sector']).sum() 
Out[322]: 
        free occupied total 
date  sector      
2017-02-01 A   2   2  4 
      B   2   2  4 
2017-02-02 A   2   2  4 
      B   3   1  4 
関連する問題