2014-12-05 10 views
6

Nie mogę tego zrobić dla moich danych, więc najpierw próbuję konkretnego przykładu, który jest bardzo podobny. Oto dataframe:UnboundLocalError: zmienna lokalna "x" przywoływana przed przypisaniem. Właściwe wykorzystanie tPłotu w pakiecie seaborn dla ramki danych?

In [56]: 

idx = pd.DatetimeIndex(start='1990-01-01', freq='d', periods=5) 
data= pd.DataFrame({('A','a'):[1,2,3,4,5], 
        ('A','b'):[6,7,8,9,1], 
        ('B','a'):[2,3,4,5,6], 
        ('B','b'):[7,8,9,1,2]}, idx) 
Out[56]: 
A B 
a b a b 
1990-01-01 1 6 2 7 
1990-01-02 2 7 3 8 
1990-01-03 3 8 4 9 
1990-01-04 4 9 5 1 
1990-01-05 5 1 6 2 

Więc co mam nadzieję zrobić to działka seria razem z linią do tendencji centralnej wśród zmiennych (każda kolumna) dla każdej obserwacji (codziennie w indeksie), z zacieniony obszar wskazujący określony estymator błędu (prawdopodobnie tylko 95% ci) obserwacji odpowiadających każdemu dniu.

Próbowałem to:

sns.tsplot(data, time=idx) 

Ale pojawia się następujący błąd:

UnboundLocalError       Traceback (most recent call last) 
<ipython-input-57-fa07e08ead95> in <module>() 
     5      ('B','b'):[7,8,9,1,2]}, idx) 
     6 
----> 7 sns.tsplot(data, time=idx) 

C:\Users\Patrick\Anaconda\lib\site-packages\seaborn\timeseries.pyc in tsplot(data, time, unit, condition, value, err_style, ci, interpolate, color, estimator, n_boot, err_palette, err_kws, legend, ax, **kwargs) 
    253 
    254  # Pad the sides of the plot only when not interpolating 
--> 255  ax.set_xlim(x.min(), x.max()) 
    256  x_diff = x[1] - x[0] 
    257  if not interpolate: 

UnboundLocalError: local variable 'x' referenced before assignment 

Składnia tsplot jest:

sns.tsplot(data, time=None, unit=None, condition=None, value=None, err_style='ci_band', ci=68, interpolate=True, color=None, estimator=<function mean at 0x00000000044F2C18>, n_boot=5000, err_palette=None, err_kws=None, legend=True, ax=None, **kwargs) 

więc przytaczam swoje dane z indeksem jako argumentem czasu, ale nie jestem pewien, co robię źle. Nie sądzę, że potrzebuję innych argumentów dotyczących słów kluczowych, ale może to jest problem.

Jeśli mogę to zrobić z tablicą o wymiarach (jednostki, czas) Zamiast:

sns.tsplot(data.values.T, time=idx) 

mogę uzyskać oczekiwany wynik (z wyjątkiem bez sygnatury czasowe są xlabels):

enter image description here

Ale jaki jest właściwy sposób, aby to zrobić z ramką danych? Wiem, że musi to być "długa forma", ale nie jestem do końca pewien, co by to miało znaczyć dla tej konkretnej ramki.

+1

UnboundLocalError wygląda jak błąd dla mnie. . . – mgilson

+0

Bałem się tego. Widziałem coś podobnego, co wyglądało na naprawione przez zainstalowanie pakietu statsmodels, ale mam to i właśnie zaktualizowałem i ponownie spróbowałem tego samego kodu, aby mieć pewność. – pbreach

+0

Nie jestem tu ekspertem, ale wygląda na to, że może się to zdarzyć, jeśli filtr grupowy nie daje żadnych wyników: https://github.com/mwaskom/seaborn/blob/master/seaborn/timeseries.py#L201 - - Domyślny warunek dla ramki danych jest obliczany w linii 108, jeśli to w ogóle pomocne ... (Przepraszam, niewiele z faceta pand osobiście ...) – mgilson

Odpowiedz

8

Skończyło się na tym. Zasadniczo pierwsze miejsce, na które powinienem był spojrzeć, to here w sekcji zatytułowanej "Określanie danych wejściowych za pomocą długich postaci DataFrames". Co miałem zrobić to w ten sposób:

data.reset_index(inplace=True) 
data.columns = np.arange(len(data.columns)) 
melted = pd.melt(data, id_vars=0) 

Pierwsza linia przesuwa DatetimeIndex do własnej kolumny i ustawia domyślny inplace indeksu całkowitą. Druga linia robi to samo dla nagłówków, z wyjątkiem ich odrzucenia (musiałem to zrobić, ponieważ wydaje się, że nie można wykonać grupowania z wielomaindeksami). Wreszcie możemy topić dane tworząc DataFrame, który wygląda tak:

In [120]: 

melted 
Out[120]: 
0 variable value 
0 1990-01-01 1 1 
1 1990-01-02 1 2 
2 1990-01-03 1 3 
3 1990-01-04 1 4 
4 1990-01-05 1 5 
5 1990-01-01 2 6 
6 1990-01-02 2 7 
7 1990-01-03 2 8 
8 1990-01-04 2 9 
9 1990-01-05 2 1 
10 1990-01-01 3 2 
11 1990-01-02 3 3 
12 1990-01-03 3 4 
13 1990-01-04 3 5 
14 1990-01-05 3 6 
15 1990-01-01 4 7 
16 1990-01-02 4 8 
17 1990-01-03 4 9 
18 1990-01-04 4 1 
19 1990-01-05 4 2 

Teraz po DataFrame jest gotowy mogę używać tsplot tak:

sns.tsplot(melted, time=0, unit='variable', value='value') 

co w moim przypadku jest niemal tak samo, jak gdyby zrobiłem:

sns.tsplot(data.T.values, idx) 
plt.xlabel('0') 
plt.ylabel('value') 

wyjątkiem gdybym dodał żadnych warunków następnie tsplot byłoby wykreślić inne serie i uczynić legendę dla mnie.

Byłoby miło, gdyby tsplot mógł przynajmniej nanieść daty jako znaczniki czasu, biorąc pod uwagę charakter funkcji. Myślę, że korzystanie z transponowanej macierzy będzie znacznie łatwiejszą opcją dla mojej aplikacji, zamiast bezpośredniego korzystania z DataFrame.