gal*_*den 5 python numpy pandas
我最近不得不获取某些项目的最后设置状态,并标有 ID。我找到了这个答案:Python:如何获得具有它们所属组最大值的行?
令我惊讶的是,在只有 ~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
Run Code Online (Sandbox Code Playgroud)
第一个是我在链接中找到的解决方案,这似乎是一种允许更复杂操作的方法。
但是,对于我的问题,我可以对重复项进行排序和删除并重新编制索引,这会表现得更好。尤其是在更大的数据集上,这真的很重要。
我的问题:还有其他方法可以实现我想做的事情吗?可能有更好的性能?
解决此问题的另一种方法是对 groupby 使用聚合,然后对完整数据帧进行选择。
df.iloc[df.groupby('id')['date'].idxmax()]
Run Code Online (Sandbox Code Playgroud)
这似乎比您提出的解决方案快大约 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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
839 次 |
| 最近记录: |