2017-07-31 8 views
1

私はデータフレームを持っています。ここでは、1つの列に真または偽の値のみがブロック内に含まれています。たとえば:パンダのデータフレームのブロックで最初に「真」の値を見つけよう

df = 
      b 
    0  False 
    1  True 
    2  True 
    3  False 
    4  True 
    5  True 
    6  True 
    7  True 
    8  False 
    9  False 
10  False 
11  False 
12  False 
13  True 
14  True 
15  True 

私は真でブロックの先頭を見つける必要がある:

>> find_first_true(df) 
>> array([1, 4, 13]) 

どれエレガントなソリューション?提案された解決策のための

EDIT

感謝。私は、私が見つけた指標から始めて、特定の長さのブロックを抽出する最も簡単な方法は何でしょうか?

たとえば、インデックスの前に長さ4のブロック(行数)を入れる必要があります。だから、私のインデックス(以前に見つかっ)

index = array([1, 4, 13]) 

はその後、私はブロックが必要な場合:

[df.loc[0:4], df.loc[9:13]] 

または

  b 
    0  False 
    1  True 
    2  True 
    3  False 
    4  True 
    9  False 
10  False 
11  False 
12  False 
13  True 

私はインデックスをループが、詳細pandasianソリューションを不思議

ています
+0

@MedAliには、真と偽の値のブロックがあります(この例では示されています)。 True値のブロックで最初のTrueのインデックスを見つける必要があります。または、あなたが好きなら、最初の真False –

答えて

2
In [2]: df = pd.read_clipboard() 

In [3]: df 
Out[3]: 
     b 
0 False 
1 True 
2 True 
3 False 
4 True 
5 True 
6 True 
7 True 
8 False 
9 False 
10 False 
11 False 
12 False 
13 True 
14 True 
15 True 
In [11]: np.where(((df.b != df.b.shift(1)) & df.b).values)[0] 
Out[11]: array([ 1, 4, 13], dtype=int64) 
+0

の直後真実、それはかなり滑らかです。 –

+0

私は '.shift [1]'の代わりに '.diff()[1:]'を使いました。 –

+0

しかし、私は非常に最初の値が足りない。どのようにそれを選ぶ考え? –

1
def find_first_true(df): 
    #finds indexes of true elements 
    a = list(map(lambda e: e[0] + 1 if e[1] else 0, enumerate(df))) 
    a = list(filter(bool, a)) 
    a = list(map(lambda x: x - 1, a)) 

    #removes consecutive elements 
    ta = [a[0]] + list(filter(lambda x: a[x] - a[x-1] != 1, range(1, len(a)))) 
    a = list(map(lambda x: a[x], ta)) 

    return a 
1
find_first = [] 
for i in range(len(df)): 
    if (df.loc[i, 'b'] == False and df.loc[i+1, 'b'] == True): 
     find_first.append(i+1) 
関連する問題