我有以下数据帧,其中一列表示对话的每一秒的讲话者的ID(0,1),另一列表示该对话经过的秒数。
myDF = pd.DataFrame({'ID': [0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1], 'seconds': (np.arange(16))})
-------------------------------
ID Seconds
-------------------------------
0 0
0 1
0 2
0 3
1 4
1 5
1 6
1 7
0 8
0 9
0 10
0 11
1 12
1 13
1 14
1 15
-------------------------------
我只对发言者ID 1感兴趣,希望可以清楚地看到发言者1的语音边界在4-7秒之间,在12-15秒之间。我要生成的是一个单独的数据帧,其中包含每个扬声器1语音段的开始和结束,其中每一行都是一个不间断的语音时段。像这样:
--------------------------------
start end
--------------------------------
4 7
12 15
--------------------------------
我有一些无法正常工作的伪代码,希望能概述我要实现的目标,但是到目前为止,我还没有找到正确的解决方案。本质上,对于每一行,我都将ID值与上一行进行比较(因为ID的变化表示语音的开始),并将相应的秒值添加到bdry数据帧中。同样,然后将每个ID值与下一行进行比较(因为这将表示语音结束)。
bdry = pd.DataFrame(columns=['start','end'])
for i in myDF:
if i['ID'] == 1:
if i.ID != i['ID'].shift(): # compare ID with previous
bdry['start'].append(i['seconds'])
if i.ID != i['ID'].shift(-1): # compare ID with next
bdry['end'].append(i['seconds'])
答案 0 :(得分:1)
import pandas as pd
from itertools import groupby
myDF = pd.DataFrame({'ID': [0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1], 'seconds': (np.arange(16))})
tmp, m = [], myDF['ID'] == 1
for v, g in groupby(zip(m.index, m), lambda k: k[1]):
if v:
g = list(g)
tmp.append((g[0][0], g[-1][0]))
df = pd.DataFrame(tmp, columns=['start', 'end'])
print(df)
打印:
start end
0 4 7
1 12 15
答案 1 :(得分:1)
使用以下代码:
result = myDF.groupby((myDF.ID != myDF.ID.shift()).cumsum()).agg(
ID=('ID', 'first'), start=('seconds', 'first'), end=('seconds', 'last'))\
.query('ID == 1').drop(columns='ID').reset_index(drop=True)
对于您的数据样本,结果是:
start end
0 4 7
1 12 15