2017-01-04 15 views
1

私は以前に同様の質問質問:Pandas Conditional Column Countパンダ条件付き列数(複雑なマッピング)

をしかし、そのように修正:

私はこのようになりますデータフレームがあります。

a1 | a2 | b3 | b4 | b5 | c | d1 | d2 | d3 | d4 | d5 
1 | 2 | 3 | 4 | 5 | 1 | 1 | 0 | 0 | 0 | 0 
1 | 4 | 5 | 3 | 2 | 0 | 0 | 1 | 1 | 1 | 0 
2 | 3 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 

を私は"a_count"と "b_count"の2つの列を作成する必要があります。

本質的に、D1-D5でブールフラグはA1/A2/B3/B4/B5に相当します。即ち、第1の行において、d1に対して、「1」は、a1の下の第1の行に対する実体に対応する。

d1-d5の列は、a1/a2/b3/b4/b5の列と均等に一致すると見なすことができます(つまり、合計#は等しくなり、またはbに対応する「d」列があります)。

私は「a_count」と「b_count」の列を持っている私の元の質問に似た何かをしたいが、条件が若干異なっています。以前は、すべてのものに対して1つの列 'd'がありました。現在、特定の列に対応するように分割しているので...

'a'で始まる列は、に対応します。 'd'列== 1、c == 0行全体に対して。だから、例えば:

anyone = df[['c', 'd']].eq(1).any(1) 
df['a_count'] = df.filter(like='a').eq(1).sum(1) * anyone 
df['b_count'] = df.filter(like='b').eq(1).sum(1) * anyone 

しかし、それに伴う問題は、私はできないということである。

a1 | a2 | b3 | b4 | b5 | c | d1 | d2 | d3 | d4 | d5 | a_count | b_count 
1 | 2 | 3 | 4 | 5 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 
1 | 4 | 5 | 3 | 2 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 
2 | 3 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 1 

私は当初、(ユーザーが元のスレッドにコメントしていること)、このようなものを使用するのではと思いましたd1、a2/d2、b3/d3、b4/d4、b5/d5の間の一致を保証するために、

私の直感は、(下記参照)本当に複雑np.whereステートメントを使用することです。しかし、これを行うには、よりエレガントな方法があった場合、私はありました

df['a_count'] = df['z1'] + df['z2'] 
df['b_count'] = df['z3'] + df['z4'] + df['z5'] 

はので、私はこれを行うための、よりエレガントな方法であることを次に

df['z1'] = np.where(((df['c'] == 0) & (df['a1'] == 1) & (df['d1'] == 1), 1, 0) 
df['z2'] = np.where(((df['c'] == 0) & (df['a2'] == 1) & (df['d2'] == 1), 1, 0) 
df['z3'] = np.where(((df['c'] == 0) & (df['b3'] == 1) & (df['d3'] == 1), 1, 0) 
df['z4'] = np.where(((df['c'] == 0) & (df['b4'] == 1) & (df['d4'] == 1), 1, 0) 
df['z5'] = np.where(((df['c'] == 0) & (df['b5'] == 1) & (df['d5'] == 1), 1, 0) 

、...知りませんでした無駄な列を作成せず、テーブルを不必要に大きくしないでください...

あなたが d最初に、マッピング aため b列を dictを使用することができます
+0

私は理解している場合わかりません。 a = {'a1': 'd1'、 'a2': 'd2'} 'と ' b = {'b4': 'd4'、 'b5': 'd5' 'b3': 'd3'} '? – jezrael

+0

もしc == 0&a1 == 1&d1 == 1ならば、それは1 と数えます。それに加えて、c == 0&a2 == 1&d2 == 1なら、a_count total 2 もし: c == 0&a2 == 1&d2 == 0の場合、a_countの合計はちょうど1(最初の値から)です。 辞書を使用してデータフレームをマスクすることはできますか? – shishy

+0

しかし、あなたのコードは 'a_count = 0,1,2'と' b_count = 0,2,2'を返さないので、ちょっと混乱します。どうして? – jezrael

答えて

1

d = {'a1':'d1','a2':'d2','b4':'d4','b5':'d5','b3':'d3'} 

その後mulことにより、複数のマスク(intに変換避けwarningためneccesaryである)とsumとの最後のfilter

df1 = (df[list(d.keys())] == 1).mul((df[list(d.values())] == 1).astype(int).values, axis=0) 
           .mul(df.c == 0, axis=0) 
print (df1) 
    a2 b5 b4 b3 a1 
0 0 0 0 0 0 
1 0 0 0 0 0 
2 0 0 0 1 0 

df['a_count'] = df1.filter(like='a').sum(axis=1) 
df['b_count'] = df1.filter(like='b').sum(axis=1) 
print (df) 
    a1 a2 b3 b4 b5 c d1 d2 d3 d4 d5 a_count b_count 
0 1 2 3 4 5 1 1 0 0 0 0  0  0 
1 1 4 5 3 2 0 0 1 1 1 0  0  0 
2 2 3 1 1 0 0 0 0 1 0 1  0  1 

もう1つ、よりダイナミックで、より複雑なソリューションMultiIndex

#keep original df 
df2 = df.copy() 
#set index with columns not matches 
df = df.set_index('c') 
#create Multiindex with ints and strings 
a = df.columns.str.extract('(\d+)', expand=False).astype(int) 
b = df.columns.str.extract('([A-Za-z]+)', expand=False) 
mux = pd.MultiIndex.from_arrays([a,b]) 
df.columns = mux 
#SORT INDEX FOR ALIGN ab dataframe with d 
df = df.sort_index(axis=1) 
print (df) 
    1  2  3  4  5 
    a d a d b d b d b d 
c        
1 1 1 2 0 3 0 4 0 5 0 
0 1 0 4 1 5 1 3 1 2 0 
0 2 0 3 0 1 1 1 0 0 1 
#select columns with a,b 
idx = pd.IndexSlice 
ab = df.loc[:, idx[:, ['a','b']]] 
print (ab) 
    1 2 3 4 5 
    a a b b b 
c    
1 1 2 3 4 5 
0 1 4 5 3 2 
0 2 3 1 1 0 

#select columns with d 
d = df.loc[:, idx[:, 'd']] 
print (d) 
    1 2 3 4 5 
    d d d d d 
c    
1 1 0 0 0 0 
0 0 1 1 1 0 
0 0 0 1 0 1 
#multiple masks 
df1 = (ab == 1).mul((d == 1).astype(int).values, axis=0) 
       .mul(df.index == 0, axis=0) 
       .reset_index(drop=True) 
print (df1) 
    1 2 3 4 5 
    a a b b b 
0 0 0 0 0 0 
1 0 0 0 0 0 
2 0 0 1 0 0 

#select columns with a and b 
df2['a_count'] = df1.loc[:, idx[:, 'a']].sum(axis=1) 
df2['b_count'] = df1.loc[:, idx[:, 'b']].sum(axis=1) 
print (df2) 
    a1 a2 b3 b4 b5 c d1 d2 d3 d4 d5 a_count b_count 
0 1 2 3 4 5 1 1 0 0 0 0  0  0 
1 1 4 5 3 2 0 0 1 1 1 0  0  0 
2 2 3 1 1 0 0 0 0 1 0 1  0  1 
+0

ああ、とてもクールです。そのような方法で辞書を使うことは考えなかった! – shishy

+0

はい、それは最も難しい問題でしたが、私はあなたを助けることができてうれしいです。受付いただきありがとうございます! – jezrael

関連する問題