python - 将时间序列列与条件相加
问题描述
我目前正在处理从工程工厂收到的一些数据,数据(大致)如下所示:
df = pd.DataFrame({'ID' : np.random.randint(1,25,size=5),
'on/off' : np.random.randint(0,2,size=5),
'Time' : pd.date_range(start='01/01/2019',periods=5,freq='5s')})
print(df)
ID on/off Time
0 17 0 2019-01-01 00:00:00
1 21 0 2019-01-01 00:00:05
2 12 1 2019-01-01 00:00:10
3 12 1 2019-01-01 00:00:15
4 12 0 2019-01-01 00:00:20
on/off 列中的 0 和 1 对应于机器的开启或关闭时间(0 = on 1 = off)
目前,我使用下面这行漂亮的代码来获取我的列之间的差异,因为数据正在滚动
df['Time Difference'] = (df.time - df.time.shift())
print(df)
ID on/off Time Time Difference
0 17 0 2019-01-01 00:00:00 NaT
1 21 0 2019-01-01 00:00:05 00:00:05
2 12 1 2019-01-01 00:00:10 00:00:05
3 12 1 2019-01-01 00:00:15 00:00:05
4 12 0 2019-01-01 00:00:20 00:00:05
现在因为这个数据框非常冗长(每周我会收到大约 150k 行)
在下一个 0 出现之前,计算机器关闭时间(df['on/off] == 1)的最佳方法是什么?因此,在 2019 年 1 月 1 日的上述示例中,ID 为 12 的机器在 00:00:20 恢复之前没有运行 15 秒
我真的很困惑这个..!我可以按 ID、开关、日期、时间戳对它进行分组,但我不确定如何处理单个列中的滚动数据位。非常感谢任何帮助或建议。
DN。
解决方案
这是一种方法,它适用于一个简单的例子,一台机器在一天的过程中会在开启和关闭之间变化。无论机器是否处于第一行on
或状态,它都可以工作。off
df = pd.DataFrame({'ID': [12, 12, 12, 12, 12],
'on/off': [0,0,1,0,1],
'Time': ['2019-01-01 00:00:00', '2019-01-01 00:00:05', '2019-01-01 00:00:10','2019-01-01 00:00:15','2019-01-01 00:00:20']
})
ID on/off Time
0 12 0 2019-01-01 00:00:00
1 12 0 2019-01-01 00:00:05
2 12 1 2019-01-01 00:00:10
3 12 0 2019-01-01 00:00:15
4 12 1 2019-01-01 00:00:20
- 首先,我确保
Time
列 dtype 是 datetime64:
df['Time'] = pd.to_datetime(df['Time'])
- 然后我得到状态改变的所有行的索引(从
off
到on
,或从on
到off
:
s = df[df['on/off'].shift(1) != df['on/off']].index
df = df.loc[s]
- 然后我创建一个名为 的列
time shift
,它显示电源状态更改的最近行的时间戳:
df['time shift'] = df['Time'].shift(1)
此时数据框如下所示:
ID on/off Time time shift
0 12 0 2019-01-01 00:00:00 NaT
2 12 1 2019-01-01 00:00:10 2019-01-01 00:00:00
3 12 0 2019-01-01 00:00:15 2019-01-01 00:00:10
4 12 1 2019-01-01 00:00:20 2019-01-01 00:00:15
- 现在,由于我们要计算机器关闭的持续时间,我只查看状态变为的行索引
on
:
r = df[df['on/off'] == 1].index
df = df.loc[r]
此时,数据框如下所示。请注意,该time shift
列显示的是机器最近关闭的时间点,该时间早于Time
列中显示的时间,即机器重新打开时的时间戳。找出这两列之间的差异将为我们提供机器在白天关闭的每个持续时间的长度:
ID on/off Time time shift
2 12 1 2019-01-01 00:00:10 2019-01-01 00:00:00
4 12 1 2019-01-01 00:00:20 2019-01-01 00:00:15
off
以下行通过将机器处于其状态的每个时期的持续时间相加来计算总停机时间:
(df['Time'] - df['time shift']).sum()
哪个输出:
Timedelta('0 days 00:00:15')
关于 Pandas.shift()
方法如何工作的一些附加上下文:
Shift 获取列中的所有行,并将它们向前或向后移动一定量。.shift(1)
告诉 pandas 将每行的索引向前或向上.shift(-1)
移动 1。告诉 pandas 将每行的索引向后或向下移动 1。或者,.shift(1)
让您查看前一行的列的值索引,并.shift(-1)
让您在下一行索引处查看列的值,相对于列中的给定行。这是一种比较不同行的列值的便捷方法,无需使用 for 循环。
推荐阅读
- ruby-on-rails-6 - Rails 6 Mina 部署在预编译时失败
- python - 使用 rpy2 将 python 数据框字符列转换为 r
- bootstrap-4 - Bootstrap:如何在不定义每个屏幕尺寸的情况下始终占用 6 列
- css - 链接按钮 onClick 在 React 中不起作用,css 将按钮更改为链接?
- arrays - 如何合并和删除这个数组
- node.js - 如何在启动时运行某个文件夹中的所有 node.js 文件?
- json - 从 ArcGis 数据库中抓取不返回数据?
- python - “str”对象没有属性:BeautifulSoup Python 中的“后代”
- r - 在 RStudio 中绘制阻塞?
- python - 使用 Dash、Plotly 和 Python 的多个折线图