2013-07-22 5 views
4

Я читаю несколько электронных таблиц таймсеров в dataframe pandas и объединяю их вместе с общим индексом datetime pandas. Регистратор данных, регистрировавший тайм-сайт, не на 100% точнее, что делает передискретизацию очень раздражающей, потому что в зависимости от того, будет ли время немного выше или ниже отбираемого интервала, он создаст NaN и начнет делать мои ряды похожими на ломаную линию. Вот мой кодКруглый индекс индексов pandas?

def loaddata(filepaths): 
    t1 = time.clock() 
    for i in range(len(filepaths)): 
     xl = pd.ExcelFile(filepaths[i]) 
     df = xl.parse(xl.sheet_names[0], header=0, index_col=2, skiprows=[0,2,3,4], parse_dates=True) 
     df = df.dropna(axis=1, how='all') 
     df = df.drop(['Decimal Year Day', 'Decimal Year Day.1', 'RECORD'], axis=1) 

     if i == 0: 
      dfs = df 
     else: 
      dfs = concat([dfs, df], axis=1) 
    t2 = time.clock() 
    print "Files loaded into dataframe in %s seconds" %(t2-t1) 

files = ["London Lysimeters corrected 5min.xlsx", "London Water Balance 5min.xlsx"] 
data = loaddata(files) 

Вот идея индекса:

data.index

класс 'pandas.tseries.index.DatetimeIndex'> [2012-08-27 12: 05: 00,000002, ..., 2013-07-12 15: 10: 00,000004] Длина: 91910, Freq: Нет, Timezone: Нет

что бы самый быстрый и общий для округления индекса до ближайшей минуты?

ответ

6

Вот небольшой трюк. Время в наносекундах (если смотреть как np.int64). Так круглые до минут в наносекундах.

In [75]: index = pd.DatetimeIndex([ Timestamp('20120827 12:05:00.002'), Timestamp('20130101 12:05:01'), Timestamp('20130712 15:10:00'), Timestamp('20130712 15:10:00.000004') ]) 

In [79]: index.values 
Out[79]: 
array(['2012-08-27T08:05:00.002000000-0400', 
     '2013-01-01T07:05:01.000000000-0500', 
     '2013-07-12T11:10:00.000000000-0400', 
     '2013-07-12T11:10:00.000004000-0400'], dtype='datetime64[ns]') 

In [78]: pd.DatetimeIndex(((index.asi8/(1e9*60)).round()*1e9*60).astype(np.int64)).values 
Out[78]: 
array(['2012-08-27T08:05:00.000000000-0400', 
     '2013-01-01T07:05:00.000000000-0500', 
     '2013-07-12T11:10:00.000000000-0400', 
     '2013-07-12T11:10:00.000000000-0400'], dtype='datetime64[ns]') 
+0

Работает идеально и очень быстро! Я не знал, что вы могли бы обработать datetimeindex таким образом – pbreach

+0

вы на самом деле * имеете *, чтобы обрабатывать их под капотом (который обычно скрывает '' index'') – Jeff

+3

это также может быть хорошим дополнением к индексу кода, вы можете следить за этой проблемой: https://github.com/pydata/pandas/issues/4314 – Jeff

0

Для столбцов данных; Использование: round_hour (df.Start_time)

def round_hour(x,tt=''): 
    if tt=='M': 
     return pd.to_datetime(((x.astype('i8')/(1e9*60)).round()*1e9*60).astype(np.int64)) 
    elif tt=='H': 
     return pd.to_datetime(((x.astype('i8')/(1e9*60*60)).round()*1e9*60*60).astype(np.int64)) 
    else: 
     return pd.to_datetime(((x.astype('i8')/(1e9)).round()*1e9).astype(np.int64)) 
4

выпуск 4314 упоминается Джеффом теперь закрыт, и round() метод был добавлен для DatetimeIndex, Timestamp, TimedeltaIndex и Timedelta в панд 0.18.0. Теперь мы можем сделать следующее:

In[109]: index = pd.DatetimeIndex([pd.Timestamp('20120827 12:05:00.002'), pd.Timestamp('20130101 12:05:01'), pd.Timestamp('20130712 15:10:30'), pd.Timestamp('20130712 15:10:31')]) 

In[110]: index.values 
Out[110]: 
array(['2012-08-27T12:05:00.002000000', '2013-01-01T12:05:01.000000000', 
     '2013-07-12T15:10:30.000000000', '2013-07-12T15:10:31.000000000'], dtype='datetime64[ns]') 

In[111]: index.round('min') 
Out[111]: 
DatetimeIndex(['2012-08-27 12:05:00', '2013-01-01 12:05:00', 
       '2013-07-12 15:10:00', '2013-07-12 15:11:00'], 
       dtype='datetime64[ns]', freq=None) 

round() принимает параметр частоты. Псевдонимы для него перечислены here.

+0

Да, 'round()' решил! –

Смежные вопросы