Уточнение временного ряда Python: из 'секунд' в 'секунды.микросекунды'
Есть таблица данных df с временным рядом datetime - показания прибора, который снимает данные от 1010 до 1030 раз в секунду (варьируется от количества успевших проскочить по кабелю за секунду пакетов). И у всех 1010-1030 показаний характеристик (которых всего 22, но это мы опустим) одинаковое значение datetime. Условно выглядит следующим образом:
>>> 2022-06-17 08:21:51 13819 1.07
>>> 2022-06-17 08:21:51 13820 1.08
>>> 2022-06-17 08:21:51 13821 1.07
>>> 2022-06-17 08:21:51 13822 1.08
>>> 2022-06-17 08:21:51 13823 1.08
. . .
>>> 2022-06-17 08:21:52 14724 1.08
>>> 2022-06-17 08:21:52 14725 1.08
>>> 2022-06-17 08:21:52 14726 1.08
. . .
>>> 2022-06-17 08:21:53 15527 1.09
>>> 2022-06-17 08:21:53 15528 1.09
>>> 2022-06-17 08:21:53 15529 1.09
>>> 2022-06-17 08:21:53 15530 1.09
Необходимо получить таблицу, в которой значения 'datetime' для каждой секунды разбиваются на микросекунды. Посчитал количество разбиений для каждого шага
counters=df.groupby(df['datetime'].tolist(),as_index=True).size()
Понимаю, что нужен цикл, где на каждой итерации нужно будет прибавлять к последующему значению в столбце дополнительно
pd.Timedelta(pd.offsets.Micro(round(1/counters[j]*1000000,0)))
Но как правильно реализовать это в цикле - что-то допетрить не могу. Такая реализация:
for i in df.index:
for j in counters.index:
countsum=pd.Timedelta(pd.offsets.Micro(0))
if df.iloc[i]['datetime'] == j:
df.iloc[i]['datetime']+=countsum
countsum+=pd.Timedelta(pd.offsets.Micro(round(1/counters[j]*1000000,0)))
Не работает. Пишет: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame
Ответы (2 шт):
я не уверен, что правильно понял вопрос, однако могу предложить такое не особо изящное решение:
import pandas as pd
import numpy as np
from io import StringIO
data = '''2022-06-17 08:21:51,13819,1.07
2022-06-17 08:21:51,13820,1.08
2022-06-17 08:21:51,13821,1.07
2022-06-17 08:21:51,13822,1.08
2022-06-17 08:21:51,13823,1.08
2022-06-17 08:21:52,14724,1.08
2022-06-17 08:21:52,14725,1.08
2022-06-17 08:21:52,14726,1.08
2022-06-17 08:21:53,15527,1.09
2022-06-17 08:21:53,15528,1.09
2022-06-17 08:21:53,15529,1.09
2022-06-17 08:21:53,15530,1.09'''
df = pd.read_csv(StringIO(data), index_col=0, parse_dates=[0], header=None)
res = pd.DataFrame()
for i, g in df.groupby(df.index):
lims = [min(g[1]), max(g[1])]
r = pd.DataFrame(index=pd.date_range(start=i, periods=1000000, freq='U'),
data = np.linspace(lims[0], lims[1], 1000000))
res = pd.concat([res, r])
тогда
print(res.head())
print(res.tail())
дадут:
0
2022-06-17 08:21:51.000000 13819.000000
2022-06-17 08:21:51.000001 13819.000004
2022-06-17 08:21:51.000002 13819.000008
2022-06-17 08:21:51.000003 13819.000012
2022-06-17 08:21:51.000004 13819.000016
и
0
2022-06-17 08:21:53.999995 15529.999988
2022-06-17 08:21:53.999996 15529.999991
2022-06-17 08:21:53.999997 15529.999994
2022-06-17 08:21:53.999998 15529.999997
2022-06-17 08:21:53.999999 15530.000000
соответственно
UPDATE
Если нужно просо сделать индекс уникальным, равномерно распределив значения для каждой секунды, то можно попробовать так:
res = pd.DataFrame()
for i, g in df.groupby(df.index):
t = pd.date_range(start=i, end=i+pd.DateOffset(seconds=1), periods=len(g))
g = g.set_index(t)
res = pd.concat([res, g])
res:
1 2
2022-06-17 08:21:51.000000000 13819 1.07
2022-06-17 08:21:51.250000000 13820 1.08
2022-06-17 08:21:51.500000000 13821 1.07
2022-06-17 08:21:51.750000000 13822 1.08
2022-06-17 08:21:52.000000000 13823 1.08
2022-06-17 08:21:52.000000000 14724 1.08
2022-06-17 08:21:52.500000000 14725 1.08
2022-06-17 08:21:53.000000000 14726 1.08
2022-06-17 08:21:53.000000000 15527 1.09
2022-06-17 08:21:53.333333333 15528 1.09
2022-06-17 08:21:53.666666666 15529 1.09
2022-06-17 08:21:54.000000000 15530 1.09
у меня получилось сделать вот таким неказистым способом:
df['datetime'] = df['datetime'] + (pd.to_timedelta(df.groupby('datetime')
.apply(lambda x: x.assign(d=round(1000000/len(x)))
.cumsum().shift().fillna(0))['d']))
>>> df
'''
datetime 1 2
0 2022-06-17 08:21:51.000000000 13819 1.07
1 2022-06-17 08:21:51.000200000 13820 1.08
2 2022-06-17 08:21:51.000400000 13821 1.07
3 2022-06-17 08:21:51.000600000 13822 1.08
4 2022-06-17 08:21:51.000800000 13823 1.08
5 2022-06-17 08:21:52.000000000 14724 1.08
6 2022-06-17 08:21:52.000333333 14725 1.08
7 2022-06-17 08:21:52.000666666 14726 1.08
8 2022-06-17 08:21:53.000000000 15527 1.09
9 2022-06-17 08:21:53.000250000 15528 1.09
10 2022-06-17 08:21:53.000500000 15529 1.09
11 2022-06-17 08:21:53.000750000 15530 1.09