Pandas

2016-05-08 3 views
1

の前のセルの値にカウントを追加する別の列 'A'のブール値に応じて、ある列 'B'に値を追加しようとしています。したがって、 'A'が真であれば、 'A'が偽である限り、カウントを開始します(つまり、それぞれ新しい行を1つ追加します)。 'A'がTrueの場合はリセットし、再度カウントを開始します。私は 'for'ループでこれを行うことができましたが、これは非常に時間がかかります。効率的な解決策がなくなるのではないかと疑問に思っていますか?Pandas

結果は次のようになります。

Date  A  B 
01.2010 False 0 
02.2010 True 1 
03.2010 False 2 
04.2010 False 3 
05.2010 True 1 
06.2010 False 2 

答えて

1

あなたがgroupbycumcountcumsumを使用することができます。

print df 
    Date  A 
0 1.201 False 
1 1.201 True 
2 1.201 False 
3 2.201 True 
4 3.201 False 
5 4.201 False 
6 5.201 True 
7 6.201 False 
roll = df.A.cumsum() 
print roll 
0 0 
1 1 
2 1 
3 2 
4 2 
5 2 
6 3 
7 3 
Name: A, dtype: int32 

df['B'] = df.groupby(roll).cumcount() + 1 
#if in first values are False, output is 0 
df.loc[roll == 0 , 'B'] = 0 
print df 
    Date  A B 
0 1.201 False 0 
1 1.201 True 1 
2 1.201 False 2 
3 2.201 True 1 
4 3.201 False 2 
5 4.201 False 3 
6 5.201 True 1 
7 6.201 False 2 
0

おかげで、私はこれに似た別のポストから解決策を得た:

rolling_count = 0 
def set_counter(val): 

    if val == False: 

    global rolling_count 
    rolling_count +=1 

    else: 

    val == True 
    rolling_count = 1 

    return rolling_count 

df['B'] = df['A'].map(set_counter) 
+0

私は両方のソリューションのタイミングをテストし、最初にソリューションに異なる出力 - 最初の行はソリューションに '1'を持ち、' ​​B'列に '0'はありません。そして、 'len(df)= 7000':%timeit(al(df1))100ループでタイミングを確認した場合、3ループ:3.75ms /ループと%timeit(jez(df))ループ100回のうち、 3:ループ毎2.29ms」となる。最後に受諾のために2ポイントを失った。しかし、それがあなたのソリューションを受け入れるほうが良いと考えるならば、それはあなた次第です。 – jezrael

+0

必要なら、問題ありません。 ;) – jezrael

+0

@ jezrael、多くのありがとう。 Excel/vbaから来て、わたしは自分の提示したソリューションをより直感的に見つけ出し、実際に仕事をしました。それにもかかわらず、あなたの解決策はもっとパンダです。私はまだcumcount()とcumsum()の違いを調べなければなりません。 –