Как узнать прерывистый указатель даты и времени? Как взять среднее по непрерывному индексу? - PullRequest
0 голосов
/ 03 мая 2018

У меня есть данные временного ряда. Но данные имеют разрыв. (2005-03-02 02:08:00 отсутствует).

Мне нужен новый столбец C, такой что C(i)=A(i)+B(i)+average, где мое среднее значение - это среднее значение B до разрыва (02:08:00).

average=Data.loc['2005-03-02 02:05:30':'2005-03-02 02:07:30',['B']].mean(axis=0)  
After discontinuity we have to again recalculate average till next discontinuity  
average=Data.loc['2005-03-02 02:08:30':'2005-03-02 02:11:00',['B']].mean(axis=0)

Ввод

Date,A,B  
2005-03-02 02:05:30,1,3   
2005-03-02 02:06:00,2,4   
2005-03-02 02:06:30,3,5  
2005-03-02 02:07:00,4,6  
2005-03-02 02:07:30,5,7  
2005-03-02 02:08:30,7,9  
2005-03-02 02:09:00,7,9  
2005-03-02 02:09:30,7,9  
2005-03-02 02:10:00,8,12  
2005-03-02 02:10:30,9,13  
2005-03-02 02:11:00,10,14

Выход

Date,A,B,C  
2005-03-02 02:05:30,1,3,9  
2005-03-02 02:06:00,2,4,11  
2005-03-02 02:06:30,3,5,13  
2005-03-02 02:07:00,4,6,15  
2005-03-02 02:07:30,5,7,17  
2005-03-02 02:08:30,7,9,28  
2005-03-02 02:09:00,7,9,28  
2005-03-02 02:09:30,7,9,28  
2005-03-02 02:10:00,8,12,32  
2005-03-02 02:10:30,9,13,34  
2005-03-02 02:11:00,10,14,36  

Как я могу найти разрыв в моем индексе ?.

Как я могу сделать все это с помощью панд?

Ответы [ 3 ]

0 голосов
/ 03 мая 2018

Шаг 1: чтение данных в кадре

import pandas as pd
from io import StringIO

y = '''Date,A,B
2005-03-02 02:05:30,1,3   
2005-03-02 02:06:00,2,4   
2005-03-02 02:06:30,3,5  
2005-03-02 02:07:00,4,6  
2005-03-02 02:07:30,5,7  
2005-03-02 02:08:30,7,9  
2005-03-02 02:09:00,7,9  
2005-03-02 02:09:30,7,9  
2005-03-02 02:10:00,8,12  
2005-03-02 02:10:30,9,13  
2005-03-02 02:11:00,10,14'''

df = pd.read_csv(StringIO(y), index_col='Date')

Шаг 2: преобразование в указатель даты и времени

df.index = pd.to_datetime(df.index)

Шаг 2: Повторная выборка с продолжительностью 30 с

new = df.resample('30s').mean()

Выход:

                        A   B  
Date                           
2005-03-02 02:05:30   1.0   3.0
2005-03-02 02:06:00   2.0   4.0
2005-03-02 02:06:30   3.0   5.0
2005-03-02 02:07:00   4.0   6.0
2005-03-02 02:07:30   5.0   7.0
2005-03-02 02:08:00   NaN   NaN
2005-03-02 02:08:30   7.0   9.0
2005-03-02 02:09:00   7.0   9.0
2005-03-02 02:09:30   7.0   9.0
2005-03-02 02:10:00   8.0  12.0
2005-03-02 02:10:30   9.0  13.0
2005-03-02 02:11:00  10.0  14.0

Шаг 3: Разделить фрейм данных по NaN-строкам и получить идентификатор группы

new["group_no"] = new.T.isnull().all().cumsum()

Выход:

                        A   B    group_no
Date                                     
2005-03-02 02:05:30   1.0   3.0         0
2005-03-02 02:06:00   2.0   4.0         0
2005-03-02 02:06:30   3.0   5.0         0
2005-03-02 02:07:00   4.0   6.0         0
2005-03-02 02:07:30   5.0   7.0         0
2005-03-02 02:08:00   NaN   NaN         1
2005-03-02 02:08:30   7.0   9.0         1
2005-03-02 02:09:00   7.0   9.0         1
2005-03-02 02:09:30   7.0   9.0         1
2005-03-02 02:10:00   8.0  12.0         1
2005-03-02 02:10:30   9.0  13.0         1
2005-03-02 02:11:00  10.0  14.0         1

Шаг 4: Получите среднее значение B для каждого group_no

new['Bmean'] = new.groupby('group_no').transform('mean').B

Выход:

                        A     B  group_no  Bmean
Date                                            
2005-03-02 02:05:30   1.0   3.0         0    5.0
2005-03-02 02:06:00   2.0   4.0         0    5.0
2005-03-02 02:06:30   3.0   5.0         0    5.0
2005-03-02 02:07:00   4.0   6.0         0    5.0
2005-03-02 02:07:30   5.0   7.0         0    5.0
2005-03-02 02:08:00   NaN   NaN         1   11.0
2005-03-02 02:08:30   7.0   9.0         1   11.0
2005-03-02 02:09:00   7.0   9.0         1   11.0
2005-03-02 02:09:30   7.0   9.0         1   11.0
2005-03-02 02:10:00   8.0  12.0         1   11.0
2005-03-02 02:10:30   9.0  13.0         1   11.0
2005-03-02 02:11:00  10.0  14.0         1   11.0

Шаг 5: применить необходимые преобразования и удалить лишние столбцы

new['C'] = new['A'] + new['B'] + new['Bmean']
new.drop(['group_no', 'Bmean'], axis=1, inplace=True)

Выход:

                        A     B     C
Date                                 
2005-03-02 02:05:30   1.0   3.0   9.0
2005-03-02 02:06:00   2.0   4.0  11.0
2005-03-02 02:06:30   3.0   5.0  13.0
2005-03-02 02:07:00   4.0   6.0  15.0
2005-03-02 02:07:30   5.0   7.0  17.0
2005-03-02 02:08:00   NaN   NaN   NaN
2005-03-02 02:08:30   7.0   9.0  27.0
2005-03-02 02:09:00   7.0   9.0  27.0
2005-03-02 02:09:30   7.0   9.0  27.0
2005-03-02 02:10:00   8.0  12.0  31.0
2005-03-02 02:10:30   9.0  13.0  33.0
2005-03-02 02:11:00  10.0  14.0  35.0
0 голосов
/ 03 мая 2018

Я предлагаю использовать:

#if unique values in index use reindex 
df = Data.reindex(pd.date_range(Data.index.min(), Data.index.max(), freq='30S'))
#if non unique values in index
#df = df.resample('30s').mean()

#get mask for NaNs rows
mask = df.isnull().all(axis=1)
#get sum of all columns
s1 = df.sum(axis=1)
#if need sum only A, B columns
#s1 = df[['A', 'B']].sum(axis=1)
#create column for grouping
df['C'] = mask.cumsum()
#filter out NaNs rows
df = df[~mask]
#transform mean and add sum
df['C'] = df.groupby('C')['B'].transform('mean') + s1
print (df)
                        A     B     C
2005-03-02 02:05:30   1.0   3.0   9.0
2005-03-02 02:06:00   2.0   4.0  11.0
2005-03-02 02:06:30   3.0   5.0  13.0
2005-03-02 02:07:00   4.0   6.0  15.0
2005-03-02 02:07:30   5.0   7.0  17.0
2005-03-02 02:08:30   7.0   9.0  27.0
2005-03-02 02:09:00   7.0   9.0  27.0
2005-03-02 02:09:30   7.0   9.0  27.0
2005-03-02 02:10:00   8.0  12.0  31.0
2005-03-02 02:10:30   9.0  13.0  33.0
2005-03-02 02:11:00  10.0  14.0  35.0

Еще одно решение, спасибо @iDrwish за предложение:

Сначала получите разницу (diff) индекса (еще не реализовано, поэтому сначала преобразуйте индекс в серию по to_series), сравните с 30 s Timedelta и создайте группы cumsum.

Последнее использование transform с mean и добавление суммы столбцов:

g = Data.index.to_series().diff().gt(pd.Timedelta(30, unit='s')).cumsum()
Data['C'] = Data.groupby(g)['B'].transform('mean') + Data.sum(axis=1)
#if need specify columns
#Data['C'] = Data.groupby(g)['B'].transform('mean') + Data['A'] + Data['B']
print (Data)
                      A   B   C
Date                           
2005-03-02 02:05:30   1   3   9
2005-03-02 02:06:00   2   4  11
2005-03-02 02:06:30   3   5  13
2005-03-02 02:07:00   4   6  15
2005-03-02 02:07:30   5   7  17
2005-03-02 02:08:30   7   9  27
2005-03-02 02:09:00   7   9  27
2005-03-02 02:09:30   7   9  27
2005-03-02 02:10:00   8  12  31
2005-03-02 02:10:30   9  13  33
2005-03-02 02:11:00  10  14  35
0 голосов
/ 03 мая 2018

Если точка описана как P (v, t). A = (3,1) и B = (10,5).

Таким образом, любой C (v, t) = A (v) + (B (v) -A (v)) * ((C (t) -A (t)): (B (t) -A ( т)).

A(v,1) = 3 
C(v,2) = 3 + (10-3) * ((2-1):(5-1)) = 4,75
C(v,3) = 3 + (10-3) * ((3-1):(5-1)) = 6,5
C(v,4) = 3 + (10-3) * ((4-1):(5-1)) = 8,25
B(v,5) = 10
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...