从熊猫列中检索唯一元素的最有效方法?

时间:2018-07-10 14:53:32

标签: python performance pandas datetime series

我有一列日期时间对象的pandas列,我想从此列中提取唯一的列表。最有效的方法是什么?

编辑:不确定熊猫如何看待执行操作的顺序

3 个答案:

答案 0 :(得分:4)

如果考虑速度,则来自Engineero的数据

Array

答案 1 :(得分:4)

您可以使用pd.Series.dt.year,然后使用pd.Series.unique

使用来自@Engineero的数据在以下Python 3.6 / Pandas 0.19上进行计时。

%timeit df['time'].dt.year.unique().tolist()                  # 739 µs per loop
%timeit df['time'].apply(lambda x: x.year).unique().tolist()  # 5.9 ms per loop
%timeit list(set(df['time'].dt.year.values))                  # 823 µs per loop

答案 2 :(得分:3)

我举了一个例子,为我们提供了165年的1000行:

base = datetime.today()
date_list = [base + x*timedelta(days=60) for x in range(0, 1000)]
df = pd.DataFrame(data={'times': date_list})

尝试一系列不同的选项,并按从快到慢的顺序列出它们:

  • 直接在dt.year.unique()列上使用times

    df.times.dt.year.unique()
    398 µs ± 5.99 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
    
  • setdt.year.values结合使用时,我们可以获得与dt.year.unique()相同的性能,但可变性更大:

    set(df.times.dt.year.values)
    422 µs ± 34.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
    
  • 使用apply

    df.times.apply(lambda x: x.year).unique()
    5.51 ms ± 117 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    
  • 使用set和列表理解:

    years = set([time.year for time in df.times])
    3.48 ms ± 68.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    
  • 有趣的是,使用语法上几乎相同的集合和生成器,我们可以更接近df.apply

    years = set((time.year for time in df.times))
    5.85 ms ± 198 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    
  • 并结合使用np.unique和列表理解:

    np.unique([time.year for time in df.times])
    6.09 ms ± 130 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    

至少到目前为止, df.times.dt.year.unique() 看来是最快的。如果我想到其他人,我会将其添加到列表中。