我正在使用 pandas.DataFrame
存储在第二个间隔采样的 3 小时传感器数据。因此,每一秒,我都会添加一行并删除超过 3 小时的行。
目前,我的效率很低:
record = pd.DataFrame.from_records([record], index='Date')
if self.data.empty:
#logger.debug('Creating data log')
self.data = record
else:
#logger.debug('Appending new record')
self.data = self.data.append(record)
start = now - self.keepInMemory
self.data = self.data[self.data.index > start]
即,创建一个新的 DataFrame,然后附加它,然后删除旧记录。它速度慢、效率低,而且肯定会重新分配大量内存。
我要找的是:
- 预分配的DataFrame
- 删除旧记录(不重新分配)
- 添加新记录
实现该目标的最 Pandas 风格的方法是什么?
谢谢。
附言我设法找到的关于 SO 的唯一相关问题是:deque in python pandas但它没有帮助。
更新:使用 DataFrame 而不是 deque 是一项要求,因为其他模块使用 self.data
作为计算通用条件的服务,例如('最后 15 分钟的 std() 与第一个' 和类似的不同)。强调一下,它不仅仅是为了记录数据,而是为其他模块提供高效便捷地计算各种通用条件的能力。
我怀疑可能有一个聪明的索引游戏(例如 data.index = np.roll(data.index,1))
然后替换最后一行,但直到现在我可以不知道如何有效地做到这一点。新记录与其他记录具有相同的格式,因此应该是可能的。
最佳答案
进行中
请参阅下面的评论。在我能解决问题之前,我会保留答案。我不想让任何人认为这可以解决问题。
考虑具有时间序列索引 tidx
的数据帧 df
。 tidx
从 70 天的日期开始。
tidx = pd.date_range('2011-03-01', periods=70)
df = pd.DataFrame(dict(A=np.arange(70)), tidx)
假设我们得到一个新的时间戳,我们将为其记录新的数据。我碰巧只是在现有天数的最大值上加了一天,但这应该无关紧要。我们可以通过将索引值等于新日期的行分配给 df
系列来追加新行。我们使用 loc
来做到这一点。
这个操作应该就地
相当有效。
new_index = df.index.max() + pd.offsets.Day()
df.loc[new_index] = pd.Series([99], df.columns)
现在我们可以定义您希望使用 pd.offsets
对象保留的时间量。我选择 60 天用于演示目的。三小时本来是 pd.offsets.Hour(3)
。我找到太旧的索引值,然后我删除
它们...再次,inplace
keep = pd.offsets.Day(60)
drops = df.index[df.index < (df.index.max() - keep)]
df.drop(drops, inplace=True)
您应该能够应用它并且应该比您正在做的事情更有效率。
关于python - 无需重新分配即可在 pandas.DataFrame 中快速删除和添加行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41527069/