2012-12-06 35 views
3

給定一個時間序列s,帶有日期時間索引,我希望能夠通過日期字符串爲時間序列建立索引。我誤解這應該如何工作?通過日期字符串索引時間序列

import pandas as pd 
url = 'http://ichart.finance.yahoo.com/table.csvs=SPY&d=12&e=4&f=2012&g=d&a=01&b=01&c=2001&ignore=.csv' 
df = pd.read_csv(url, index_col='Date', parse_dates=True) 
s = df['Close'] 
s['2012-12-04'] 

結果:

TimeSeriesError       Traceback (most recent call last) 
<ipython-input-244-e2ccd4ecce94> in <module>() 
     2 df = pd.read_csv(url, index_col='Date', parse_dates=True) 
     3 s = df['Close'] 
----> 4 s['2012-12-04'] 

    G:\Python27-32\lib\site-packages\pandas\core\series.pyc in __getitem__(self, key) 
    468  def __getitem__(self, key): 
    469   try: 
--> 470    return self.index.get_value(self, key) 
    471   except InvalidIndexError: 
    472    pass 

    G:\Python27-32\lib\site-packages\pandas\tseries\index.pyc in get_value(self, series, key) 

    1030 
    1031    try: 
-> 1032     loc = self._get_string_slice(key) 
    1033     return series[loc] 
    1034    except (TypeError, ValueError, KeyError): 

G:\Python27-32\lib\site-packages\pandas\tseries\index.pyc in _get_string_slice(self, key) 
    1077   asdt, parsed, reso = parse_time_string(key, freq) 
    1078   key = asdt 
-> 1079   loc = self._partial_date_slice(reso, parsed) 
    1080   return loc 
    1081 

G:\Python27-32\lib\site-packages\pandas\tseries\index.pyc in _partial_date_slice(self, reso, parsed) 
    992  def _partial_date_slice(self, reso, parsed): 
    993   if not self.is_monotonic: 
--> 994    raise TimeSeriesError('Partial indexing only valid for ordered ' 
    995         'time series.') 
    996 

TimeSeriesError: Partial indexing only valid for ordered time series. 

更具體的(也許是迂腐..),什麼是這裏的2個時間序列之間的區別:

import pandas as pd 
url = 'http://ichart.finance.yahoo.com/table.csv?  s=SPY&d=12&e=4&f=2012&g=d&a=01&b=01&c=2001&ignore=.csv' 
s = pd.read_csv(url, index_col='Date', parse_dates=True)['Close'] 
rng = date_range(start='2011-01-01', end='2011-12-31') 
ts = Series(randn(len(rng)), index=rng) 
print ts.__class__ 
print ts.index[0].__class__ 
print s1.__class__ 
print s1.index[0].__class__ 
print ts[ts.index[0]] 
print s[s.index[0]] 
print ts['2011-01-01'] 
try: 
    print s['2012-12-05'] 
except: 
    print "doesn't work" 

結果:

<class 'pandas.core.series.TimeSeries'> 
<class 'pandas.lib.Timestamp'> 
<class 'pandas.core.series.TimeSeries'> 
<class 'pandas.lib.Timestamp'> 
-0.608673793503 
141.5 
-0.608673793503 
doesn't work 
+0

我在該網址上發生404錯誤。如果你複製一些表格,或者甚至更好'df.to_dict()'的輸出,它會更容易。 –

回答

2

嘗試使用索引編制Timestamp對象:

>>> import pandas as pd 
>>> from pandas.lib import Timestamp 
>>> url = 'http://ichart.finance.yahoo.com/table.csv?s=SPY&d=12&e=4&f=2012&g=d&a=01&b=01&c=2001&ignore=.csv' 
>>> df = pd.read_csv(url, index_col='Date', parse_dates=True) 
>>> s = df['Close'] 
>>> s[Timestamp('2012-12-04')] 
141.25 
+0

是的,謝謝,我可以看到那會起作用。我的問題是爲什麼s ['2012-12-04']沒有。它是一個錯誤,還是它應該如何爲具有日期時間索引的時間系列工作? – user1878647

+0

@ user1878647它有一個不是日期時間的時間戳記索引,儘管您也可以使用它的日期時間進行查找。你不能做的是用一個未知的日期格式的字符串查找(一方面,它可能不清楚它應該被解釋爲哪個日期)。我會說這不是一個錯誤。 –

+0

@hayden以上示例中的ts和s都具有時間戳索引,但行爲不同。 – user1878647

1

當時間序列沒有下令,你給一個局部時間戳(例如日期而不是日期),不清楚應選擇哪個日期時間。

不能假設每個日期只有一個日期時間對象,儘管在這個例子中,這裏有幾個選項,但在這裏拋出錯誤似乎更安全,而不是猜測用戶的動機。 (我們可以返回一個類似於.ix['2011-01']的系列/列表,但如果在其他情況下返回一個數字,這可能會引起混淆,我們可以嘗試返回「最接近的匹配」......但這也沒有意義。)

在一個有序的情況下,我們選擇所選日期的第一個日期時間更容易。

您可以在此看到的行爲在這個簡單的例子:

import pandas as pd 
from numpy.random import randn 
from random import shuffle 
rng = pd.date_range(start='2011-01-01', end='2011-12-31') 
rng2 = list(rng) 
shuffle(rng2) # not in order 
rng3 = list(rng) 
del rng3[20] # in order, but no freq 

ts = pd.Series(randn(len(rng)), index=rng) 
ts2 = pd.Series(randn(len(rng)), index=rng2) 
ts3 = pd.Series(randn(len(rng)-1), index=rng3) 

ts.index 
<class 'pandas.tseries.index.DatetimeIndex'> 
[2011-01-01 00:00:00, ..., 2011-12-31 00:00:00] 
Length: 365, Freq: D, Timezone: None 

ts['2011-01-01'] 
# -1.1454418070543406 

ts2.index 
<class 'pandas.tseries.index.DatetimeIndex'> 
[2011-04-16 00:00:00, ..., 2011-03-10 00:00:00] 
Length: 365, Freq: None, Timezone: None 

ts2['2011-01-01'] 
#...error which you describe 
TimeSeriesError: Partial indexing only valid for ordered time series 

ts3.index 
<class 'pandas.tseries.index.DatetimeIndex'> 
[2011-01-01 00:00:00, ..., 2011-12-31 00:00:00] 
Length: 364, Freq: None, Timezone: None 

ts3['2011-01-01'] 
1.7631554507355987 


rng4 = pd.date_range(start='2011-01-01', end='2011-01-31', freq='H') 
ts4 = pd.Series(randn(len(rng4)), index=rng4) 

ts4['2011-01-01'] == ts4[0] 
# True # it picks the first element with that date 

我不認爲這是一個錯誤,但我張貼作爲an issue on github

+0

謝謝。我明白了你的觀點。我只是無視時間... – user1878647

0

雖然熊貓教程很有啓發性,但我認爲提出的原始問題值得直接回答。我遇到了同樣的問題,將雅虎的圖表信息,以可能被切成一個數據幀,等我發現,這是唯一需要的是:

import pandas as pd 
import datetime as dt 

def dt_parser(date): 
return dt.datetime.strptime(date, '%Y-%m-%d') + dt.timedelta(hours=16) 

url = 'http://ichart.finance.yahoo.com/table.csvs=SPY&d=12&e=4&f=2012&g=d&a=01&b=01&c=2001&ignore=.csv' 
df = pd.read_csv(url, index_col=0, parse_dates=True, date_parser=dt_parser) 
df.sort_index(inplace=True) 
s = df['Close'] 
s['2012-12-04']  # now should work 

的「絕招」是包括我自己date_parser。我猜在read_csv中有一些更好的方法來做到這一點,但是這至少產生了一個被索引並可以被分割的DataFrame。