我有一个超过200万条记录的数组,每条记录的datetime.datetime格式都有10分钟的解析时间戳,以及其他列中的其他几个值。
我只想保留在数组中出现20次或更多次时间戳的记录。最快的方法是什么?我有足够的内存,所以我正在寻找处理速度。
我在列表理解中尝试了[] .count(),但开始失去等待它完成的意志。我也试过numpy.bincount(),但不幸的是它不喜欢datetime.datetime
我们非常感谢任何建议。 谢谢!
答案 0 :(得分:3)
我根据以下建议编辑此内容以使用np.unique
包含时间。这是迄今为止最好的解决方案
In [10]: import pandas as pd
import numpy as np
from collections import Counter
#create a fake data set
dates = pd.date_range("2012-01-01", "2015-01-01", freq="10min")
dates = np.random.choice(dates, 2000000, replace=True)
根据以下建议,以下是迄今为止最快的建议:
In [32]: %%timeit
values, counts = np.unique(dates, return_counts=True)
filtered_dates = values[counts>20]
10 loops, best of 3: 150 ms per loop
使用计数器,您可以创建每个项目计数的字典,然后将其转换为pd.Series
以进行过滤
In [11]: %%timeit
foo = pd.Series(Counter(dates))
filtered_dates = np.array(foo[foo > 20].index)
1 loop, best of 3: 12.3 s per loop
对于包含200万个项目的数组而言,这不是太糟糕了,而不是:
In [12]: dates = list(dates)
filtered_dates = [e for e in set(dates) if dates.count(e) > 20]
我不会等到列表理解版本完成...
答案 1 :(得分:1)
实际上可能会尝试np.unique
。在numpy v1.9 + unique
中可以返回一些额外内容,例如unique_indices
,unique_inverse
,unique_counts
。
如果你想使用熊猫,它会非常简单并且可能非常快。您可以使用groupby filter。类似的东西:
out = df.groupby('timestamp').filter(lambda x: len(x) > 20)
答案 2 :(得分:1)
Numpy在这些类型的操作上比熊猫慢,因为meta_info_list = [{
'title': article.find_element_by_xpath('.//article/h2').text,
'share count': article.find_element_by_xpath('.//footer/div/a/span').text,
'points': article.find_element_by_xpath('.//footer/div[2]/div[1]/div[3]').text
} for article in article_elements]
排序,而pandas中的机器并不需要。此外,这更加惯用。
熊猫
np.unique
Numpy(来自其他国家)
In [22]: %%timeit
....: i = Index(dates)
....: i[i.value_counts()>20]
....:
10 loops, best of 3: 78.2 ms per loop
In [23]: i = Index(dates)
In [24]: i[i.value_counts()>20]
Out[24]:
DatetimeIndex(['2013-06-16 20:40:00', '2013-05-28 03:00:00', '2013-10-31 19:50:00', '2014-06-20 13:00:00', '2013-07-08 21:40:00', '2012-02-26 17:00:00', '2013-01-02 15:40:00', '2012-08-24 02:00:00',
'2014-10-17 08:20:00', '2012-07-27 20:10:00',
...
'2014-08-07 05:10:00', '2014-05-21 08:10:00', '2014-03-09 12:50:00', '2013-05-10 02:30:00', '2013-04-15 20:20:00', '2012-06-23 05:20:00', '2012-07-06 16:10:00', '2013-02-14 12:20:00',
'2014-10-27 03:10:00', '2013-09-04 12:00:00'],
dtype='datetime64[ns]', length=2978, freq=None)
In [25]: len(i[i.value_counts()>20])
Out[25]: 2978
答案 3 :(得分:0)
Sort
您的数组frequency >= 20
运行时间是O(nlog(n)),而你的列表理解可能是O(n ** 2)......这对200万个条目产生了很大影响。
根据数据的结构,您可能只能从保存数据的numpy数组中对所需的轴和数据进行排序。
答案 4 :(得分:0)
感谢您的所有建议。
我最终做了一些与词典完全不同的事情,发现它对我所需的处理速度要快得多。
我创建了一个字典,其中包含一组唯一的时间戳作为键,空列表作为值,然后通过无序列表(或数组)循环一次,并使用我想要计算的值填充值列表。
再次感谢!