通过熊猫列迭代分配事件

问题描述 投票:-1回答:2

假设我有一个像[0,0,0,1,0,0,1,0]这样的列表。

只要迭代器遇到1,包含1的前面列表就会分配给一个事件。这一直持续到下一个1遇到。因此,在这种情况下,有2个事件。

但是如果列表像[0,0,1,1,0,0,1]那样,这仍然算作2个事件,因为连续的1个被认为是一起的。

截至目前,我不包括像[1,0,0,1]这样的案件。

如果左边的0或1属于哪个事件,可以创建一个新列来反映,如事件1或事件2等。

我发现一些使用zip但我的情况有些不同。我该如何处理?

python pandas iterator
2个回答
1
投票

IIUC,定义一个事件:

  • 它必须从0(??)开始,以'1'结尾,并且必须至少有一个'1'
  • 如果两个相邻的行是 从0-> 0,1-> 1,0-> 1,然后在同一事件中 从1-> 0,不同的事件

以下我使用(df.c.diff() < 0).cumsum()+1来识别event_id,并根据是否有'1'表示调整最后一个event_id组:

import pandas as pd
import numpy as np

l = [0,0,0,1,1,0,0,1,0]
df = pd.DataFrame(l, columns=['c'])

# event_id changes when df.c.diff() < 0
event_id = (df.c.diff() < 0).cumsum()+1

#event_id
#Out[233]: 
#0    1
#1    1
#2    1
#3    1
#4    1
#5    2
#6    2
#7    2
#8    3

# the last event_id sequence might not be an event if it does not contain any '1'
m1 = df.groupby(event_id).c.transform(max) == 1
# if you need at least one '0' in an event, then adjust condition to m1&m2 in np.where() and since the first event_id might be skipped thus its calculation should be based on if the first row is an '1'
#event_id = (df.c.diff() < 0).cumsum()+ np.where(df.c.iloc[0]==1,0,1)
#m2 = df.groupby(event_id).c.transform(min) == 0
#df['event'] = np.where(m1&m2, event_id.map('Event-{}'.format), 'Not an event')

df['event'] = np.where(m1, event_id.map('Event-{}'.format), 'Not an event')
# df
# Out[235]: 
#   c         event
#0  0       Event-1
#1  0       Event-1
#2  0       Event-1
#3  1       Event-1
#4  1       Event-1
#5  0       Event-2
#6  0       Event-2
#7  1       Event-2
#8  0  Not an event

注意:df.groupby(event_id).c.transform(max) == 1表示至少有一个'1'在同一个event_id组中,因此有资格参加一个事件。


1
投票

你可以使用itertools.groupby

import itertools 
l=[0,0,1,1,0,0,1]
[list(y)[0]==1 for x , y in itertools.groupby(l)]
Out[853]: [False, True, False, True]
sum([list(y)[0]==1 for x , y in itertools.groupby(l)])
Out[854]: 2
© www.soinside.com 2019 - 2024. All rights reserved.