14

私はpandas.DatetimeIndex、例えば:

pd.date_range('2012-1-1 02:03:04.000',periods=3,freq='1ms')
>>> [2012-01-01 02:03:04, ..., 2012-01-01 02:03:04.002000]

Timestamp日付 ( s) を最も近い秒に丸めたいと思います。それ、どうやったら出来るの?期待される結果は次のようになります。

[2012-01-01 02:03:04.000000, ..., 2012-01-01 02:03:04.000000]

を変更せずにNumpydatetime64[ns]を秒に丸めることでこれを達成することは可能dtype [ns]ですか?

np.array(['2012-01-02 00:00:00.001'],dtype='datetime64[ns]')
4

4 に答える 4

16

更新: DatetimeIndex / datetime64 列に対してこれを行っている場合、より良い方法はnp.round、適用/マップ経由ではなく直接使用することです:

np.round(dtindex_or_datetime_col.astype(np.int64), -9).astype('datetime64[ns]')

古い回答(さらに説明あり):

@Mattiの答えは明らかにあなたの状況に対処する正しい方法ですが、タイムスタンプを最も近い秒に丸める方法を追加すると思いました:

from pandas.lib import Timestamp

t1 = Timestamp('2012-1-1 00:00:00')
t2 = Timestamp('2012-1-1 00:00:00.000333')

In [4]: t1
Out[4]: <Timestamp: 2012-01-01 00:00:00>

In [5]: t2
Out[5]: <Timestamp: 2012-01-01 00:00:00.000333>

In [6]: t2.microsecond
Out[6]: 333

In [7]: t1.value
Out[7]: 1325376000000000000L

In [8]: t2.value
Out[8]: 1325376000000333000L

# Alternatively: t2.value - t2.value % 1000000000
In [9]: long(round(t2.value, -9)) # round milli-, micro- and nano-seconds
Out[9]: 1325376000000000000L

In [10]: Timestamp(long(round(t2.value, -9)))
Out[10]: <Timestamp: 2012-01-01 00:00:00>

したがって、これをインデックス全体に適用できます。

def to_the_second(ts):
    return Timestamp(long(round(ts.value, -9)))

dtindex.map(to_the_second)
于 2012-12-09T14:28:02.343 に答える
15

round()pandas 0.18.0 では、DatetimeIndex、Timestamp、TimedeltaIndex、Timedelta のメソッドが追加されました。これで、次のことができます。

In[114]: index = pd.DatetimeIndex([pd.Timestamp('2012-01-01 02:03:04.000'), pd.Timestamp('2012-01-01 02:03:04.002'), pd.Timestamp('20130712 02:03:04.500'), pd.Timestamp('2012-01-01 02:03:04.501')])

In[115]: index.values
Out[115]: 
array(['2012-01-01T02:03:04.000000000', '2012-01-01T02:03:04.002000000',
       '2013-07-12T02:03:04.500000000', '2012-01-01T02:03:04.501000000'], dtype='datetime64[ns]')

In[116]: index.round('S')
Out[116]: 
DatetimeIndex(['2012-01-01 02:03:04', '2012-01-01 02:03:04',
               '2013-07-12 02:03:04', '2012-01-01 02:03:05'],
              dtype='datetime64[ns]', freq=None)

round()周波数パラメータを受け入れます。その文字列エイリアスはここにリストされています。

于 2016-09-03T19:02:03.680 に答える
4

There is little point in changing the index itself - since you can just generate using date_range with the desired frequency parameter as in your question.

I assume what you are trying to do is change the frequency of a Time Series that contains data, in which case you can use resample (documentation). For example if you have the following time series:

dt_index = pd.date_range('2012-1-1 00:00.001',periods=3, freq='1ms')
ts = pd.Series(randn(3), index=dt_index)


2012-01-01 00:00:00           0.594618
2012-01-01 00:00:00.001000    0.874552
2012-01-01 00:00:00.002000   -0.700076
Freq: L

Then you can change the frequency to seconds using resample, specifying how you want to aggregate the values (mean, sum etc.):

ts.resample('S', how='sum')

2012-01-01 00:00:00    0.594618
2012-01-01 00:00:01    0.174475
Freq: S
于 2012-12-09T14:17:10.880 に答える
3

より一般的な丸めには、Pandasオブジェクトがメソッドを含む標準ライブラリ API をTimestampほとんど使用しているという事実を利用できます。datetime.datetimedatetime.datetime.replace()

したがって、マイクロ秒の丸めの問題を解決するには、次のようにします。

import datetime
import pandas as pd

times = pd.date_range('2012-1-1 02:03:04.499',periods=3,freq='1ms')
# Add 5e5 microseconds and truncate to simulate rounding
times_rounded = [(x + datetime.timedelta(microseconds=5e5)).replace(microsecond=0) for x in times]

from IPython.display import display
print('Before:')
display(list(times))
print('After:')
display(list(times_rounded))

出力:

Before:
[Timestamp('2012-01-01 02:03:04.499000', offset='L'),
 Timestamp('2012-01-01 02:03:04.500000', offset='L'),
 Timestamp('2012-01-01 02:03:04.501000', offset='L')]
After:
[Timestamp('2012-01-01 02:03:04', offset='L'),
 Timestamp('2012-01-01 02:03:05', offset='L'),
 Timestamp('2012-01-01 02:03:05', offset='L')]

たとえば、同じ手法を使用して、最も近い日に丸めることができます (うるう秒などを気にしない限り)。

times = pd.date_range('2012-1-1 08:00:00', periods=3, freq='4H')
times_rounded = [(x + datetime.timedelta(hours=12)).replace(hour=0, second=0, microsecond=0) for x in times]

この SO 投稿に触発されました: https://stackoverflow.com/a/19718411/1410871

于 2015-08-28T22:01:29.727 に答える