Python Pandas—自上次在200万行数据帧中出现以来的分钟数
例如,我有以下数据帧:Python Pandas—自上次在200万行数据帧中出现以来的分钟数,python,pandas,dataframe,vectorization,Python,Pandas,Dataframe,Vectorization,例如,我有以下数据帧: Date indicator_1 indicator_2 2013-04-01 03:50:00 x w 2013-04-01 04:00:00 y u 2013-04-01 04:15:00 z v 2013-04-01 04:25:00 x w 2013-04-01 04:25:00
Date indicator_1 indicator_2
2013-04-01 03:50:00 x w
2013-04-01 04:00:00 y u
2013-04-01 04:15:00 z v
2013-04-01 04:25:00 x w
2013-04-01 04:25:00 z u
2013-04-01 04:30:00 y u
2013-04-01 04:35:00 y w
2013-04-01 04:40:00 z w
2013-04-01 04:40:00 x u
2013-04-01 04:40:00 y v
2013-04-01 04:50:00 x w
我的目标是使用以下规则创建两列:
- 第一列应给出自指示器_1列上最后一次出现“x”以来的分钟数
- 第二列应该给出自指示器_1和指示器_2列上最后一次出现对“y”和“u”以来的分钟数
Date desired_column_1 desired_column_2 indicator_1 indicator_2
2013-04-01 03:50:00 NaN NaN x w
2013-04-01 04:00:00 10.0 NaN y u
2013-04-01 04:15:00 25.0 15.0 z v
2013-04-01 04:25:00 35.0 25.0 x w
2013-04-01 04:25:00 35.0 25.0 z u
2013-04-01 04:30:00 5.0 30.0 y u
2013-04-01 04:35:00 10.0 5.0 y w
2013-04-01 04:40:00 15.0 10.0 z w
2013-04-01 04:40:00 15.0 10.0 x u
2013-04-01 04:40:00 15.0 10.0 y v
2013-04-01 04:50:00 10.0 20.0 x w
主要问题是整个数据帧有超过200万行,因此使用循环太耗时。有没有办法对这个问题实施矢量化方法
dataframe的python代码如下所示:
d = {'Date': ['2013-04-01 03:50:00','2013-04-01 04:00:00','2013-04-01
04:15:00','2013-04-01 04:25:00','2013-04-01 04:25:00',
'2013-04-01 04:30:00','2013-04-01 04:35:00','2013-04-01 04:40:00','2013-04-01 04:40:00','2013-04-01 04:40:00',
'2013-04-01 04:50:00'], 'indicator_1': ['x','y','z','x','z','y','y','z','x','y','x'],
'indicator_2': ['w','u','v','w','u','u','w','w','u','v','w'],
'desired_column_1': [np.nan, 10, 25, 35, 35,5,10,15,15,15,10],
'desired_column_2': [np.nan, np.nan, 15, 25, 25,30,5,10,10,10,20]}
df = pd.DataFrame(data=d)
首先,确保列
['Date']
是datetime对象,并获取一列来表示行与行之间的时间差
df.Date = pd.to_datetime(df.Date)
df['minD'] = (df.Date -df.Date.shift(1)).astype('timedelta64[m]')
接下来,为您的条件创建分组键。我们向下移动一行,因为我们正在查找自上次x以来的时间,这也可以包括下一个x值。如果不转换,我们就不会将下一个x包含在我们的组中
mask2 = (df.indicator_1.str.cat(df.indicator_2) == 'yu').cumsum().shift(1)
mask1 = (df.indicator_1 == 'x').cumsum().shift(1)
现在,根据掩码和cumsum()
微小差异进行分组,但我们需要过滤掉布尔值中的cumsum()
<1,因为条件尚未发生,因此应该缺少时间差的值
df['desired_column_1'] = df.groupby(mask1.where(mask1 > 0)).minD.cumsum()
df['desired_column_2'] = df.groupby(mask2.where(mask2 > 0)).minD.cumsum()
现在,您可以通过正向填充数据来替换这些列中的0值
df.desired_column_1 = df.desired_column_1.replace(0,method='ffill')
df.desired_column_2 = df.desired_column_2.replace(0,method='ffill')
这是真的
Date indicator_1 indicator_2 desired_column_1 \
0 2013-04-01 03:50:00 x w NaN
1 2013-04-01 04:00:00 y u 10.0
2 2013-04-01 04:15:00 z v 25.0
3 2013-04-01 04:25:00 x w 35.0
4 2013-04-01 04:25:00 z u 35.0
5 2013-04-01 04:30:00 y u 5.0
6 2013-04-01 04:35:00 y w 10.0
7 2013-04-01 04:40:00 z w 15.0
8 2013-04-01 04:40:00 x u 15.0
9 2013-04-01 04:40:00 y v 15.0
10 2013-04-01 04:50:00 x w 10.0
desired_column_2
0 NaN
1 NaN
2 15.0
3 25.0
4 25.0
5 30.0
6 5.0
7 10.0
8 10.0
对案例1使用这个答案,然后为案例2创建一个组合的指示符,同样,在python中使用for循环也不是很理想,我想,谢谢你的回答!我在第一种情况下尝试了您的代码,但是,我没有在所需列上获得所需的值。事实上完全不同。目标是计算变量“x”上次出现后的分钟数。哦,对不起,我不太了解您的情况,
Date indicator_1 indicator_2 desired_column_1 \
0 2013-04-01 03:50:00 x w NaN
1 2013-04-01 04:00:00 y u 10.0
2 2013-04-01 04:15:00 z v 25.0
3 2013-04-01 04:25:00 x w 35.0
4 2013-04-01 04:25:00 z u 35.0
5 2013-04-01 04:30:00 y u 5.0
6 2013-04-01 04:35:00 y w 10.0
7 2013-04-01 04:40:00 z w 15.0
8 2013-04-01 04:40:00 x u 15.0
9 2013-04-01 04:40:00 y v 15.0
10 2013-04-01 04:50:00 x w 10.0
desired_column_2
0 NaN
1 NaN
2 15.0
3 25.0
4 25.0
5 30.0
6 5.0
7 10.0
8 10.0