pandas.DataFrame中的快速行删除和添加,无需重新分配

时间:2017-01-07 22:02:52

标签: python pandas optimization memory-efficient

我使用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
  • 删除旧记录(无需重新分配)
  • 添加新记录

实现这一目标的熊猫最多的方法是什么?

谢谢。

P.S。我设法找到的唯一相关问题是:deque in python pandas但它没有帮助。

更新:使用DataFrame而非deque是一项要求,因为其他模块使用self.data作为计算通用条件的服务,例如('是最后15分钟的std()与第一个'和类似的不同。要强调,它不仅仅是为了记录数据,而是为其他模块提供高效,方便地计算各种通用条件的能力。

我怀疑可能会有一个聪明的索引游戏(例如data.index = np.roll(data.index,1))然后替换最后一行,但直到现在我无法弄清楚如何有效地做到这一点。新记录的格式与休息,所以它应该是可能的。

1 个答案:

答案 0 :(得分:0)

正在进行中

见下面的评论。我会留下答案直到我可以解决问题。我不希望任何人认为这解决了这个问题。

考虑具有时间序列索引df的数据框tidxtidx以70天的日期开始。

tidx = pd.date_range('2011-03-01', periods=70)
df = pd.DataFrame(dict(A=np.arange(70)), tidx)

假设我们得到一个新的时间戳,我们将记录新的数据。我恰巧在现有的最大日子里添加了一天,但这无关紧要。我们可以通过在索引值等于新日期的行中为df分配一个系列来追加新行。我们使用loc来执行此操作。

此操作应该inplace相当有效。

new_index = df.index.max() + pd.offsets.Day()
df.loc[new_index] = pd.Series([99], df.columns)

现在我们可以定义您想要与pd.offsets对象保持的时间量。我选择60天进行演示。三个小时就是pd.offsets.Hour(3)。我发现索引值太旧而我drop再次,inplace

keep = pd.offsets.Day(60)
drops = df.index[df.index < (df.index.max() - keep)]

df.drop(drops, inplace=True)

你应该能够应用它,并且应该比你正在做的更有效率。