我有Pandas DataFrame,有近3,000,000行。其中一列名为TIMESTAMP
,而日期时间为64。时间戳格式如下:
2015-03-31 22:56:45.510
我的目标是计算收集数据的天数。我最初的方法很简单:
(df.TIMESTAMP.max() - df.TIMESTAMP.min()).days
然而,它发生在我身上可能并不总是正确的,因为每天都没有保证收集数据。相反,我尝试使用map
和apply
计算时间戳系列中的唯一日期,并且两者都需要花费相当多的时间来处理3,000,000行:
%timeit len(df['TIMESTAMP'].map(lambda t: t.date()).unique())
1 loops, best of 3: 41.3 s per loop
%timeit len(df['TIMESTAMP'].apply(lambda t: t.date()).unique())
1 loops, best of 3: 42.3 s per loop
有没有办法加快这种计算,或采用完全不同但更好的方法?
谢谢!
答案 0 :(得分:8)
要获取您应该首先normalize
的唯一日期(要获得当天午夜的时间,请注意快速),然后使用{{ 3}}:
In [31]: df["Time"].dt.normalize().unique()
Out[31]:
array(['2014-12-31T16:00:00.000000000-0800',
'2015-01-01T16:00:00.000000000-0800',
'2015-01-02T16:00:00.000000000-0800',
'2015-01-04T16:00:00.000000000-0800',
'2015-01-05T16:00:00.000000000-0800'], dtype='datetime64[ns]')
原始答案(我误读了问题):
要获取计数,可以使用unique
,然后使用normalize
:
In [11]: df
Out[11]:
Time
0 2015-01-01
1 2015-01-02
2 2015-01-03
3 2015-01-03
4 2015-01-05
5 2015-01-06
In [12]: df['Time'].dt.normalize().value_counts()
Out[12]:
2015-01-03 2
2015-01-06 1
2015-01-02 1
2015-01-05 1
2015-01-01 1
Name: Time, dtype: int64
但也许更清洁的选择是重新取样(虽然我不确定这是否效率较低):
In [21]: pd.Series(1, df['Time']).resample("D", how="sum")
Out[21]:
Time
2015-01-01 1
2015-01-02 1
2015-01-03 2
2015-01-04 NaN
2015-01-05 1
2015-01-06 1
Freq: D, dtype: float64
答案 1 :(得分:1)
如果您的索引是DateTimeIndex,我认为您可以这样做:
print(df.groupby(df.index.date).shape)