【问题标题】:Best way to get last entries from Pandas data frame从 Pandas 数据框中获取最后一个条目的最佳方法
【发布时间】:2016-02-04 18:31:00
【问题描述】:

我最近必须获得某些项目的最后设置状态,并标有 id。我找到了这个答案:Python : How can I get Rows which have the max value of the group to which they belong?

令我惊讶的是,对于只有 ~2e6 行的数据集,它相当慢。但是我不需要获取所有最大值,只需获取最后一个。

import numpy as np
import pandas as pd

df = pd.DataFrame({
    "id": np.random.randint(1, 1000, size=5000),
    "status": np.random.randint(1, 10, size=5000),
    "date": [
        time.strftime("%Y-%m-%d", time.localtime(time.time() - x))
        for x in np.random.randint(-5e7, 5e7, size=5000)
    ],
})

%timeit df.groupby('id').apply(lambda t: t[t.date==t.date.max()])
1 loops, best of 3: 576 ms per loop

%timeit df.reindex(df.sort_values(["date"], ascending=False)["id"].drop_duplicates().index)
100 loops, best of 3: 4.82 ms per loop

第一个是我在链接中找到的解决方案,这似乎是一种允许更复杂操作的方法。

但是对于我的问题,我可以对重复项进行排序和删除并重新索引,这会更好。尤其是在更大的数据集上,这真的很重要。

我的问题:还有其他方法可以实现我想做的事情吗?可能有更好的性能?

【问题讨论】:

  • 一条评论:字符串排序比数字排序慢,因此您可以通过首先将日期列转换为日期时间类型,在第二个解决方案中获得约 3 倍的加速:df['date'] = pd.to_datetime(df['date'])

标签: python numpy pandas


【解决方案1】:

解决此问题的另一种方法是在 groupby 上使用聚合,然后在整个数据帧上进行选择。

df.iloc[df.groupby('id')['date'].idxmax()]

这似乎比您提出的解决方案快 5-10 倍(见下文)。请注意,这仅在 'date' 列是数字而非字符串类型时才有效,并且此转换还加快了基于排序的解决方案:

# Timing your original solutions:
%timeit df.groupby('id').apply(lambda t: t[t.date==t.date.max()])
# 1 loops, best of 3: 826 ms per loop
%timeit df.reindex(df.sort_values(["date"], ascending=False)["id"].drop_duplicates().index)
# 100 loops, best of 3: 5.1 ms per loop

# convert the date
df['date'] = pd.to_datetime(df['date'])

# new times on your solutions
%timeit df.groupby('id').apply(lambda t: t[t.date==t.date.max()])
# 1 loops, best of 3: 815 ms per loop
%timeit df.reindex(df.sort_values(["date"], ascending=False)["id"].drop_duplicates().index)
# 1000 loops, best of 3: 1.99 ms per loop

# my aggregation solution
%timeit df.iloc[df.groupby('id')['date'].idxmax()]
# 10 loops, best of 3: 135 ms per loop

【讨论】:

  • 在我的原始数据中,日期已经是 datetime64,但有用的信息仍然存在。聚合解决方案对我的原始数据(3 分钟 40 秒)给出了可接受的性能,在这种情况下是可行的。对于排序和删除重复项不能提供所需结果的更复杂的情况,这肯定会帮助我。谢谢!也为了快速响应。
猜你喜欢
  • 2022-06-22
  • 2021-12-09
  • 2020-10-05
  • 1970-01-01
  • 2016-11-17
  • 2016-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多