在Numpy日期时间数组中查找唯一的日期

6
我有时间序列数据(epoch, values),已经转换成(datetime, values)并储存在Numpy数组中。现在我想找到对应给定日期的第一行的索引。因此,每天只需要一个索引。
以下是一个完全使用Python编写的函数,速度非常慢。
def day_wise_datetime(datetimes,dataseries):
    unique_dates=[]
    unique_indices=[]
    for i in range(len(datetimes)):
        if datetimes[i].day not in unique_dates:
           unique_dates.append(datetimes[i])
           unique_indices.append(i)
    return [unique_dates,unique_indices]

Numpy提供了一种独特的方法,但它表示无法对日期时间进行排序。那么可以使用基于Numpy的什么技术来实现相同的功能呢?
我知道推荐使用Pandas,但是在学习它的同时,想知道是否有一些NumPy / SciPy解决方案可能足够。
编辑: datetimes变量中的值类似于。我只是切了前五个元素。
[datetime.datetime(2011, 4, 18, 18, 52, 9),
datetime.datetime(2011, 4, 18, 18, 52, 10),
datetime.datetime(2011, 4, 18, 18, 52, 11),
datetime.datetime(2011, 4, 18, 18, 52, 12),
datetime.datetime(2011, 4, 18, 18, 52, 13)]

能否提供一个简单的输入示例? - waitingkuo
@waitingkuo:添加了示例输入。 - Nipun Batra
我的回答能解决你的问题吗? - waitingkuo
1个回答

2

pandas的DataFrame提供了drop_duplicates函数,可以轻松实现您的目标:

In [121]: arr1 = np.array([dt.datetime(2013, 1, 1), dt.datetime(2013, 1, 1), dt.datetime(2013, 1, 2)]) 

In [122]: arr2 = np.array([1, 2, 3]) 

In [123]: df = pd.DataFrame({'date': arr1, 'value': arr2})

In [124]: df
Out[124]: 
                 date  value
0 2013-01-01 00:00:00      1   
1 2013-01-01 00:00:00      2   
2 2013-01-02 00:00:00      3   

In [125]: df.drop_duplicates('date')
Out[125]: 
                 date  value
0 2013-01-01 00:00:00      1   
2 2013-01-02 00:00:00      3 

编辑

一开始我误解了你的问题。请尝试以下方法:

似乎排序是你主要遇到的问题,我创建了一个反转日期时间列表作为示例:

In [74]: now = dt.datetime.utcnow()
In [75]: datetimes = [now - dt.timedelta(hours=6) * i for i in range(10)]

In [76]: datetimes
Out[76]:
[datetime.datetime(2013, 5, 8, 16, 47, 32, 60500),
 datetime.datetime(2013, 5, 8, 10, 47, 32, 60500),
 datetime.datetime(2013, 5, 8, 4, 47, 32, 60500),
 datetime.datetime(2013, 5, 7, 22, 47, 32, 60500),
 datetime.datetime(2013, 5, 7, 16, 47, 32, 60500),
 datetime.datetime(2013, 5, 7, 10, 47, 32, 60500),
 datetime.datetime(2013, 5, 7, 4, 47, 32, 60500),
 datetime.datetime(2013, 5, 6, 22, 47, 32, 60500),
 datetime.datetime(2013, 5, 6, 16, 47, 32, 60500),
 datetime.datetime(2013, 5, 6, 10, 47, 32, 60500)]

创建一个DataFrame,使用datetimes作为列,并将列名设置为date
In [81]: df = pd.DataFrame(datetimes, columns=['date'])

In [82]: df
Out[82]:
                        date
0 2013-05-08 16:47:32.060500
1 2013-05-08 10:47:32.060500
2 2013-05-08 04:47:32.060500
3 2013-05-07 22:47:32.060500
4 2013-05-07 16:47:32.060500
5 2013-05-07 10:47:32.060500
6 2013-05-07 04:47:32.060500
7 2013-05-06 22:47:32.060500
8 2013-05-06 16:47:32.060500
9 2013-05-06 10:47:32.060500

接下来,按照“date”列对你的“DataFrame”进行排序。
In [83]: df = df.sort('date')

接着为index添加一列:

In [85]: df['index'] = df['date'].apply(lambda x:x.day)

In [86]: df
Out[86]:
                        date  index
9 2013-05-06 10:47:32.060500      6
8 2013-05-06 16:47:32.060500      6
7 2013-05-06 22:47:32.060500      6
6 2013-05-07 04:47:32.060500      7
5 2013-05-07 10:47:32.060500      7
4 2013-05-07 16:47:32.060500      7
3 2013-05-07 22:47:32.060500      7
2 2013-05-08 04:47:32.060500      8
1 2013-05-08 10:47:32.060500      8
0 2013-05-08 16:47:32.060500      8

首先按照index对您的数据进行分组,然后获取每个组的第一个数据。如果您熟悉SQL语言,这就像执行SELECT FIRST(*) FROM table GROUP BY table.index操作:

In [87]: df = df.groupby('index').first()
In [88]: df
Out[88]: 
                            date
index                           
6     2013-05-06 10:47:32.060500
7     2013-05-07 04:47:32.060500
8     2013-05-08 04:47:32.060500

现在您可以获取唯一的索引:
In [91]: df.index.values
Out[91]: array([6, 7, 8])

获取唯一的日期:
In [92]: df['date'].values
Out[92]: 
array(['2013-05-06T18:47:32.060500000+0800',
   '2013-05-07T12:47:32.060500000+0800',
   '2013-05-08T12:47:32.060500000+0800'], dtype='datetime64[ns]')

由于我需要对一天内的所有记录进行数据操作,例如平均值和其他操作,因此我不想删除其他数据。此外,我的日期时间对象还包含小时、分钟和秒钟信息。 - Nipun Batra
它只是生成一个新对象,而不是替换原始对象。 - waitingkuo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接