我有超過200萬條記錄的數組,每個記錄都有一個10分鐘的datetime.datetime格式的分辨率時間戳,以及其他列中的其他幾個值。按發生頻率過濾日期時間數組
我只想保留在數組中出現20次或更多時間的記錄。什麼是最快的方法來做到這一點?我有很多內存,所以我正在尋找處理速度。
我已經嘗試[] .count()列表中的理解,但開始失去意願,等待它完成。我也試過numpy.bincount(),但不幸的是它不喜歡datetime.datetime
任何建議將不勝感激。 謝謝!
我有超過200萬條記錄的數組,每個記錄都有一個10分鐘的datetime.datetime格式的分辨率時間戳,以及其他列中的其他幾個值。按發生頻率過濾日期時間數組
我只想保留在數組中出現20次或更多時間的記錄。什麼是最快的方法來做到這一點?我有很多內存,所以我正在尋找處理速度。
我已經嘗試[] .count()列表中的理解,但開始失去意願,等待它完成。我也試過numpy.bincount(),但不幸的是它不喜歡datetime.datetime
任何建議將不勝感激。 謝謝!
Sort
您的陣列frequency >= 20
的運行時間爲O(n日誌(N)),而您的列表理解可能是O( n ** 2)......這在200萬條記錄上有相當大的差異。
根據數據結構的不同,您可能只能從包含它的numpy數組中排序所需的軸和數據。
有沒有一種快速的方法來計算事件而不必循環數據? – WRJ
沒有。你必須通過每個條目來過濾它,但是,如果數據是第一次排序,這是非常快的。 –
我在編輯這個以包含使用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萬項的數組,VS如下:
In [12]: dates = list(dates)
filtered_dates = [e for e in set(dates) if dates.count(e) > 20]
我不會等待列表理解的版本來完成...
其實可以嘗試np.unique
。在numpy v1.9 + unique
可以返回一些臨時演員,如unique_indices
,unique_inverse
,unique_counts
。
如果你想使用熊貓,這將是非常簡單,可能相當快。您可以使用groupby filter。喜歡的東西:
out = df.groupby('timestamp').filter(lambda x: len(x) > 20)
'np.unique'的好建議 – johnchase
numpy的比對這些類型的操作熊貓慢,因爲np.unique
排序,而大熊貓的機器並不需要。而且這更加地道。
熊貓
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
numpy的(來自其它溶液)
In [26]: %%timeit
values, counts = np.unique(dates, return_counts=True)
filtered_dates = values[counts>20]
....:
10 loops, best of 3: 145 ms per loop
In [27]: filtered_dates = values[counts>20]
In [28]: len(filtered_dates)
Out[28]: 2978
一致認爲,這是迄今爲止最好的解決方案,只要有熊貓可用。 – johnchase
感謝您的所有建議。
我最終完成了與字典完全不同的事情,並且發現它對於我所需的處理速度要快得多。
我創建了一個具有唯一一組時間戳作爲鍵和空列表作爲值的字典,然後通過無序列表(或數組)循環一次,並使用我想要計數的值填充值列表。
再次感謝!
'熊貓'可能會在O(n)時間做到這一點,所以我添加了標籤。 –
你能舉一個你的數組看起來像什麼樣的小例子嗎? 3-4個元素應該給我們一個足夠好的想法。 – Reti43
使用熊貓做一個組通過時間戳 – reptilicus