熊猫-带滑动窗的条件柱

时间:2019-05-17 10:46:22

标签: python pandas conditional

我有一个包含两列的df-时间戳和文本。我正在尝试使用True / false(1/0)标签标记数据。条件是,如果文本中出现“错误”一词,则在输入之前3-4小时之间的所有输入应获得1标签,其他应获得0。例如。来自这样的df:

time   text
15:00  a-ok
16:01  fine
17:00  kay
18:00  uhum
19:00  doin well
20:00  is error
20:05  still error
21:00  fine again

应转换为:

time   text       error coming
15:00  a-ok       0
16:01  fine       1
17:00  kay        1
18:00  uhum       1
19:00  doin well  1
20:00  is error   0
20:05  still error0
21:00  fine again 0

我读了一些关于用.rolling滑动窗口的知识,但是我很难将它们组合在一起。

1 个答案:

答案 0 :(得分:0)

想法是将时间转换为timedelta,使用错误过滤timedeltas,并为每个值创建带有logical_or.reduce的掩码,使用具有倒置m1的链掩码来避免error的值,并转换为整数从True/False1/0的映射:

td = pd.to_timedelta(df['time'].astype(str) + ':00')

m1 = df['text'].str.contains('error')
v = td[m1]
print (v)
5   20:00:00
6   20:05:00
Name: time, dtype: timedelta64[ns]

m2 = np.logical_or.reduce([td.between(x - pd.Timedelta(4, unit='h'), x) for x in v])
df['error coming'] = (m2 & ~m1).astype(int)
print (df)
    time         text  error coming
0  15:00         a-ok             0
1  16:01         fine             1
2  17:00          kay             1
3  18:00         uhum             1
4  19:00    doin well             1
5  20:00     is error             0
6  20:05  still error             0
7  21:00   fine again             0

编辑:

df['time'] = pd.to_datetime(df['time'])
print (df)
                 time         text
0 2019-01-26 15:00:00         a-ok
1 2019-01-26 16:01:00         fine
2 2019-01-26 17:00:00          kay
3 2019-01-26 18:00:00         uhum
4 2019-01-26 19:00:00    doin well
5 2019-01-26 20:00:00     is error
6 2019-01-26 20:05:00  still error
7 2019-01-26 21:00:00   fine again

print (df.dtypes)
time    datetime64[ns]
text            object
dtype: object

m1 = df['text'].str.contains('error')
v = df.loc[m1, 'time']
print (v)
5   2019-01-26 20:00:00
6   2019-01-26 20:05:00
Name: time, dtype: datetime64[ns]

m2 = np.logical_or.reduce([df['time'].between(x - pd.Timedelta(4, unit='h'), x) for x in v])
df['error coming'] = (m2 & ~m1).astype(int)
print (df)
                 time         text  error coming
0 2019-01-26 15:00:00         a-ok             0
1 2019-01-26 16:01:00         fine             1
2 2019-01-26 17:00:00          kay             1
3 2019-01-26 18:00:00         uhum             1
4 2019-01-26 19:00:00    doin well             1
5 2019-01-26 20:00:00     is error             0
6 2019-01-26 20:05:00  still error             0
7 2019-01-26 21:00:00   fine again             0

矢量化解决方案:

m1 = df['text'].str.contains('error')
v = df.loc[m1, 'time']
print (v)
5   2019-01-26 20:00:00
6   2019-01-26 20:05:00
Name: time, dtype: datetime64[ns]

a = v - pd.Timedelta(4, unit='h')
m = (a.values < df['time'].values[:, None]) & (v.values > df['time'].values[:, None])
df['error coming'] = (m.any(axis=1) & ~m1).astype(int)
print (df)
                 time         text  error coming
0 2019-01-26 15:00:00         a-ok             0
1 2019-01-26 16:01:00         fine             1
2 2019-01-26 17:00:00          kay             1
3 2019-01-26 18:00:00         uhum             1
4 2019-01-26 19:00:00    doin well             1
5 2019-01-26 20:00:00     is error             0
6 2019-01-26 20:05:00  still error             0
7 2019-01-26 21:00:00   fine again             0