Разделение DataFrame на разрывы в индексе datetime - PullRequest
0 голосов
/ 28 января 2019

Прежде всего, мои извинения, если название было слишком двусмысленным.

У меня есть pd.DataFrame с datetime64 в качестве индекса типа d.Эти индексы, однако, распределены неравномерно: в большинстве случаев они имеют интервал в одну минуту, но часто есть и другие интервалы, например две минуты.

Предположим, если у меня есть pd.DataFrame:

df = pd.DataFrame({'date': ['2018-11-28 13:59:00', '2018-11-28 14:00:00',
               '2018-11-28 14:01:00', '2018-11-28 14:02:00',
               '2018-11-28 14:03:00', '2018-11-28 14:05:00',
               '2018-11-28 14:06:00', '2018-11-28 14:07:00',
               '2018-11-28 14:08:00', '2018-11-28 14:09:00'], 
                   'count': np.random.randint(1, 100, 10)})
datetime_index = pd.to_datetime(df['date'])
df = df.set_index(datetime_index).drop('date', 1)
df.sort_index(inplace=True)

так, что df равно:

    count
date    
2018-11-28 13:59:00 14
2018-11-28 14:00:00 30
2018-11-28 14:01:00 2
2018-11-28 14:02:00 42
2018-11-28 14:03:00 51<<< two minutes gap
2018-11-28 14:05:00 41<<< unlike others
2018-11-28 14:06:00 48
2018-11-28 14:07:00 4
2018-11-28 14:08:00 50
2018-11-28 14:09:00 93

Моя цель состоит в том, чтобы разделить df на несколько кусков, где каждый блок имеет постоянную частоту, равную одной минуте.Таким образом, ожидаемый результат сверху стал бы:

#df0
    count
date    
2018-11-28 13:59:00 14
2018-11-28 14:00:00 30
2018-11-28 14:01:00 2
2018-11-28 14:02:00 42
2018-11-28 14:03:00 51
#df1
    count
date   
2018-11-28 14:05:00 41
2018-11-28 14:06:00 48
2018-11-28 14:07:00 4
2018-11-28 14:08:00 50
2018-11-28 14:09:00 93

Я пытался Разделить серию на промежутки времени в пандах? , что, к сожалению, было довольно устаревшим и не служило моей цели.

Я действительно достиг того, что хочу для приведенного выше примера, но фактический фрейм данных намного больше и имеет гораздо больше пробелов, что делает следующее решение крайне неэффективным:

df['diff'] = pd.Series(df.index).diff().values
dif = pd.Series(df.index).diff()
gap_index = dif[dif == pd.to_timedelta(120000000000)].index[0]
df[:gap_index], df[gap_index:]

Я бы очень хотелценим любое понимание этого вопроса

Ответы [ 2 ]

0 голосов
/ 28 января 2019

Если вы заинтересованы в создании словаря, который будет содержать все ваши отдельные фреймы данных, возможно, это должно сработать:

df['identifier']=(~df.index.to_series().diff().dt.seconds.div(60, fill_value=0).lt(2)).cumsum()

                     count  identifier
date                                  
2018-11-28 13:59:00      7           0
2018-11-28 14:00:00     49           0
2018-11-28 14:01:00     13           0
2018-11-28 14:02:00     47           0
2018-11-28 14:03:00     72           0
2018-11-28 14:05:00     33           1
2018-11-28 14:06:00     50           1
2018-11-28 14:07:00     10           1
2018-11-28 14:08:00     86           1
2018-11-28 14:09:00     40           1

Опубликуйте этот текст и добавьте группы:

d = {}
for i,grp in df.groupby('identifier'):
    d.update(dict([('df_' + str(i),grp)]))
print(d)

Вывод:

{'df_0':                      count  identifier


date                                  
 2018-11-28 13:59:00      7           0
 2018-11-28 14:00:00     49           0
 2018-11-28 14:01:00     13           0
 2018-11-28 14:02:00     47           0
 2018-11-28 14:03:00     72           0,
 'df_1':                      count  identifier
 date                                  
 2018-11-28 14:05:00     33           1
 2018-11-28 14:06:00     50           1
 2018-11-28 14:07:00     10           1
 2018-11-28 14:08:00     86           1
 2018-11-28 14:09:00     40           1}

затем вы можете просмотреть свои данные, вызвав клавиши dict:

print(d['df_1'])
                     count  identifier
date                                  
2018-11-28 14:05:00     95           1
2018-11-28 14:06:00     68           1
2018-11-28 14:07:00     19           1
2018-11-28 14:08:00      9           1
2018-11-28 14:09:00     61           1
0 голосов
/ 28 января 2019

Вот быстрое и грязное решение:

import pandas as pd
import numpy as np

df = pd.DataFrame({'date': ['2018-11-28 13:59:00', '2018-11-28 14:00:00',
           '2018-11-28 14:01:00', '2018-11-28 14:02:00',
           '2018-11-28 14:03:00', '2018-11-28 14:05:00',
           '2018-11-28 14:06:00', '2018-11-28 14:07:00',
           '2018-11-28 14:08:00', '2018-11-28 14:09:00'],
               'count': np.random.randint(1, 100, 10)})

df['date'] = pd.to_datetime(df['date'])
df.sort_index(inplace=True)

# calculate where to cut
df['cut_point'] = pd.to_datetime(df.date.shift(-1))[0:len(df)-1]- df.date[0:len(df)-1] > '00:01:00'
df['cut_point'] = df['cut_point'].shift(1)

# generate chunks
res = []
chunk = []

for i,row in df.iterrows():
    date = row['date']
    count = row['count']
    cut_point = row['cut_point']

    if cut_point == True:

        res.append(pd.DataFrame(chunk))

        del chunk[:]

        chunk.append({'date':date,'count':count})

    else:
        chunk.append({'date':date,'count':count})

res.append(pd.DataFrame(chunk))

print(res[0])

print(res[1])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...