2015-01-02 4 views
0

я пытаюсь изменить вывод следующего кода:Изменение числа индексов в DataFrame?

import numpy as np 
import pandas as pd 
from pandas import Series, DataFrame, Panel, bdate_range, DatetimeIndex, date_range 
from pandas.tseries.holiday import get_calendar 
from datetime import datetime, timedelta 
import pytz as pytz 
from pytz import timezone 

start = datetime(2013, 1, 1) 

hr1 = np.loadtxt("Spot_2013_Hour1.txt") 

index = date_range(start, end = '2013-12-31', freq='B') 
Allhrs = Series(index) 
Allhrs = DataFrame({'hr1': hr1}) 
df = Allhrs 
indexed_df = df.set_index(index) 
print indexed_df 

Ошибка:

File "<ipython-input-61-c7890d8ccb07>", line 17, in <module> 
    indexed_df = df.set_index(index) 

    File "/Applications/anaconda/lib/python2.7/site-packages/pandas/core/frame.py", line 2390, in set_index 
    frame.index = index 

    File "/Applications/anaconda/lib/python2.7/site-packages/pandas/core/generic.py", line 1849, in __setattr__ 
    object.__setattr__(self, name, value) 

    File "properties.pyx", line 65, in pandas.lib.AxisProperty.__set__ (pandas/lib.c:38491) 

    File "/Applications/anaconda/lib/python2.7/site-packages/pandas/core/generic.py", line 400, in _set_axis 
    self._data.set_axis(axis, labels) 

    File "/Applications/anaconda/lib/python2.7/site-packages/pandas/core/internals.py", line 1965, in set_axis 
    'new values have %d elements' % (old_len, new_len)) 

ValueError: Length mismatch: Expected axis has 365 elements, new values have 261 elements 

Проблема:

У меня есть временные ряды, которые я загрузить из текстового файла , Временной ряд состоит из 365 элементов, т. Е. Всех дней 2013 года. Мне нужен этот txt-файл, потому что мне нужно анализировать каждый день.

Кроме того, мне нужно проанализировать конкретные дни года 2013. Поэтому я хочу изменить чтение данных, то есть хочу видеть только рабочие дни. Кроме того, было бы замечательно видеть/печатать определенные дни.

Помощь оценили

ответ

6

Во-первых, создать DataFrame (или серии) с все дни года:

index = date_range(start='2013-1-1', end='2013-12-31', freq='D') 
df = pd.DataFrame(hr1, index=index) 

Далее используйте df.asfreq('B') для декодируют df в рабочие дни:

import numpy as np 
import pandas as pd 

# hr1 = np.loadtxt("Spot_2013_Hour1.txt") 
hr1 = np.random.random(365) 
index = date_range(start='2013-1-1', end='2013-12-31', freq='D') 
df = pd.DataFrame(hr1, index=index) 

indexed_df = df.asfreq('B') 
print(indexed_df) 

Чтобы установить частоту рабочих дней, исключая определенные дни, вы могли бы использовать offsets.CustomBusinessDay:

import pandas.tseries.offsets as offsets 
holidays = ['2013-10-03' , '2013-12-25'] 
business_days = offsets.CustomBusinessDay(holidays=holidays) 
custom_df = df.asfreq(business_days) 

Таким образом, custom_df имеет два дня меньше, чем indexed_df

In [12]: len(custom_df) 
Out[12]: 259 

In [13]: len(indexed_df) 
Out[13]: 261 

и «праздники», как '2013-10-03' не хватает:

In [18]: '2013-10-03' in indexed_df.index 
Out[18]: True 

In [19]: '2013-10-03' in custom_df.index 
Out[19]: False 

Это также полезно знать, что the reindex method может быть использован для подвыборки строк. Например, вы можете вычесть определенные дни из indexed_df.index:

idx = indexed_df.index - pd.DatetimeIndex(holidays) 
custom_df2 = df.reindex(idx) 

В результате, custom_df2 равно custom_df:

In [35]: custom_df2.equals(custom_df) 
Out[35]: True 

, но обратите внимание, что индексы немного отличаются:

In [36]: custom_df.index 
Out[36]: 
<class 'pandas.tseries.index.DatetimeIndex'> 
[2013-01-01, ..., 2013-12-31] 
Length: 259, Freq: C, Timezone: None 

In [37]: custom_df2.index 
Out[37]: 
<class 'pandas.tseries.index.DatetimeIndex'> 
[2013-01-01, ..., 2013-12-31] 
Length: 259, Freq: None, Timezone: None 

custom_df как Freq: C, а custom_df2 имеет Freq: None. freq используется определенными способами, такими как snap и to_period. Но эти методы также позволяют указать желаемую частоту в качестве аргумента, так что на практике я не нашел эту разницу большой проблемой.

+0

Спасибо! Оно работает! У меня есть еще один вопрос: как исключить определенные дни из временного ряда, скажем: 2013.10.03 и 2013.12.25? –

+0

Я добавил некоторую информацию о том, как исключить определенные дни, используя ['CustomBusinessDay'] (http://pandas.pydata.org/pandas-docs/stable/timeseries.html # custom-business-days-experimental) и (альтернативно), вызвав ['reindex'] (http://pandas.pydata.org/pandas-docs/dev/generated/pandas.DataFrame.reindex.html). – unutbu

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