Python 在不丢失信息的情况下,将Timeseries的索引从datetime64[ns]转换为datetime64[s]

Python 在不丢失信息的情况下,将Timeseries的索引从datetime64[ns]转换为datetime64[s],python,pandas,dataframe,datetime,time-series,Python,Pandas,Dataframe,Datetime,Time Series,我正在研究一个由时间戳索引的时间序列,精度为ns,但实际上应该是每秒一个。我需要以秒为单位转换这个时间戳,因为我想提取一些周期性模式,有时我会丢失数据点,在每秒对转换后的数据时间重新采样后,我会对这些数据点进行插值 data = np.array([["2019-07-12 10:39:17.817000+00:00", 45],["2019-07-12 10:39:19.007000+00:00", 45],["2019-07-12 10:39:19.996000+00:00", 40],["

我正在研究一个由时间戳索引的时间序列,精度为ns,但实际上应该是每秒一个。我需要以秒为单位转换这个时间戳,因为我想提取一些周期性模式,有时我会丢失数据点,在每秒对转换后的数据时间重新采样后,我会对这些数据点进行插值

data = np.array([["2019-07-12 10:39:17.817000+00:00", 45],["2019-07-12 10:39:19.007000+00:00", 45],["2019-07-12 10:39:19.996000+00:00", 40],["2019-07-12 10:39:20.497000+00:00", 1],["2019-07-12 10:39:21.489000+00:00", 10],["2019-07-12 10:39:22.498000+00:00", 3],["2019-07-12 10:39:23.491000+00:00", 5],["2019-07-12 10:39:24.501000+00:00", 15],["2019-07-12 10:39:25.495000+00:00", 8],["2019-07-12 10:39:26.489000+00:00", 3],["2019-07-12 10:39:27.497000+00:00", 90],["2019-07-12 10:39:28.490000+00:00", 4],["2019-07-12 10:39:29.498000+00:00", 37],["2019-07-12 10:39:30.490000+00:00", 55]])
df = pd.DataFrame(data[:, 1], index=data[:, 0], columns=["value"])
df.index=pd.to_datetime(df.index)
print(df.to_string())
                                 value
2019-07-12 10:39:17.817000+00:00    45
2019-07-12 10:39:19.007000+00:00    45
2019-07-12 10:39:19.996000+00:00    40
2019-07-12 10:39:20.497000+00:00     1
2019-07-12 10:39:21.489000+00:00    10
2019-07-12 10:39:22.498000+00:00     3
2019-07-12 10:39:23.491000+00:00     5
2019-07-12 10:39:24.501000+00:00    15
2019-07-12 10:39:25.495000+00:00     8
2019-07-12 10:39:26.489000+00:00     3
2019-07-12 10:39:27.497000+00:00    90
2019-07-12 10:39:28.490000+00:00     4
2019-07-12 10:39:29.498000+00:00    37
2019-07-12 10:39:30.490000+00:00    55
我想要的是以秒为单位转换日期时间,但这样做会产生重复的值:

df.index = df.index.round(freq="S")
print(df.to_string())
                          value
2019-07-12 10:39:18+00:00    45
2019-07-12 10:39:19+00:00    45
2019-07-12 10:39:20+00:00    40
2019-07-12 10:39:20+00:00     1
2019-07-12 10:39:21+00:00    10
2019-07-12 10:39:22+00:00     3
2019-07-12 10:39:23+00:00     5
2019-07-12 10:39:25+00:00    15
2019-07-12 10:39:25+00:00     8
2019-07-12 10:39:26+00:00     3
2019-07-12 10:39:27+00:00    90
2019-07-12 10:39:28+00:00     4
2019-07-12 10:39:29+00:00    37
2019-07-12 10:39:30+00:00    55
即使我选择“地板”而不是“圆形”,它也不会工作,因为这些值:

2019-07-12 10:39:19.007000+00:00
2019-07-12 10:39:19.996000+00:00 
有没有办法以秒为单位转换日期时间,这样它就不会创建重复的值

预期产出:

                          value
2019-07-12 10:39:17+00:00    45
2019-07-12 10:39:18+00:00    45
2019-07-12 10:39:19+00:00    40
2019-07-12 10:39:20+00:00     1
2019-07-12 10:39:21+00:00    10
2019-07-12 10:39:22+00:00     3
2019-07-12 10:39:23+00:00     5
2019-07-12 10:39:24+00:00    15
2019-07-12 10:39:25+00:00     8
2019-07-12 10:39:26+00:00     3
2019-07-12 10:39:27+00:00    90
2019-07-12 10:39:28+00:00     4
2019-07-12 10:39:29+00:00    37
2019-07-12 10:39:30+00:00    55

如果您先取整到最接近的100ms,然后使用ceil取整到最接近的秒,您将获得所需的输出

import pandas as pd

df = pd.read_csv('something.csv')

df['time'] = pd.to_datetime(df['time'], infer_datetime_format=True)
print(df)

df['time'] = df['time'].dt.round('100ms')
df['time'] = df['time'].dt.ceil('1s')
print(df)
输出:

0  2019-07-12 10:39:18+00:00     45
1  2019-07-12 10:39:19+00:00     45
2  2019-07-12 10:39:20+00:00     40
3  2019-07-12 10:39:21+00:00      1
4  2019-07-12 10:39:22+00:00     10
5  2019-07-12 10:39:23+00:00      3
6  2019-07-12 10:39:24+00:00      5
7  2019-07-12 10:39:25+00:00     15
8  2019-07-12 10:39:26+00:00      8
9  2019-07-12 10:39:27+00:00      3
10 2019-07-12 10:39:28+00:00     90
11 2019-07-12 10:39:29+00:00      4
12 2019-07-12 10:39:30+00:00     37
13 2019-07-12 10:39:31+00:00     55

我想比舍入更好的方法是通过插值将数据采样增加到固定频率,然后再进行下采样(如果上采样频率不是最终频率的倍数,则再次通过插值)。但是,没有办法在不丢失信息的情况下进行下采样(除非您的信号首先被过采样)。是的,我知道我问了很多问题,我说我不想丢失信息:),遗憾的是,这不是一个过采样信号,与所有真实数据一样,它没有被很好地收集。谢谢,我会尝试你解释的,我对使用时间序列有点陌生,所以我可能需要一段时间,但我会让你知道它是否更好。为什么第二个18得到一个值,尽管它在第一个数据帧中没有?因为我想你只是想:
df.resample('S').sum()
你考虑过时间序列的标准化吗?@Erfan因为机器发送数据太晚而出错,但理论上我应该每秒测量一次,有时,它看起来像是一秒钟有两个,但这是因为它是在前/后一秒钟。谢谢,它似乎在我的真实数据集上运行得很好,但仍然会创建一些重复项,因为类似这样的情况:
2019-07-19 06:29:01.057000+02:00
2019-07-19 06:29:02.049000+02:00
因此,这两行的第二个2位都被舍入。我试图删除一秒钟的行有重复,我成功地减少了很多重复的数量。虽然我仍然有一些问题,但我想我不会有一个完美的结果。@SmileyProd使用这个后,你能用更新的数据集发布一个新问题吗?我可能有一些想法。。