2015-10-16 20 views
15

Tôi có nhiều chuỗi thời gian khác nhau, mà tôi muốn tương quan - hay đúng hơn là, tương quan chéo - với nhau, để tìm ra thời gian trễ mà hệ số tương quan là lớn nhất.Tương quan chéo (tương quan trễ thời gian) với gấu trúc?

Tôi đã tìm thấy variousquestions và câu trả lời/liên kết thảo luận cách thực hiện điều đó với vần, nhưng điều đó có nghĩa là tôi phải biến các khung dữ liệu thành các mảng có nhiều mảng. Và kể từ khi chuỗi thời gian của tôi thường bao gồm các giai đoạn khác nhau, tôi sợ rằng tôi sẽ chạy vào hỗn loạn.

Sửa

Vấn đề tôi đang gặp khó với tất cả các NumPy/phương pháp scipy, là họ dường như thiếu nhận thức về chuỗi thời gian bản chất của dữ liệu của tôi. Khi tôi tương quan một chuỗi thời gian bắt đầu vào năm 1940 với chuỗi bắt đầu vào năm 1970, gấu trúc corr biết điều này, trong khi np.correlate chỉ tạo ra 1020 mục (độ dài của chuỗi dài hơn) đầy nan.

Các Q khác nhau về chủ đề này chỉ ra rằng cần có cách để giải quyết vấn đề độ dài khác nhau, nhưng cho đến nay, tôi đã không thấy chỉ dẫn về cách sử dụng nó trong một khoảng thời gian cụ thể. Tôi chỉ cần thay đổi 12 tháng theo gia số 1, để xem thời gian tương quan tối đa trong vòng một năm.

Edit2

Một số dữ liệu mẫu tối thiểu:

import pandas as pd 
import numpy as np 
dfdates1 = pd.date_range('01/01/1980', '01/01/2000', freq = 'MS') 
dfdata1 = (np.random.random_integers(-30,30,(len(dfdates1)))/10.0) #My real data is from measurements, but random between -3 and 3 is fitting 
df1 = pd.DataFrame(dfdata1, index = dfdates1) 
dfdates2 = pd.date_range('03/01/1990', '02/01/2013', freq = 'MS') 
dfdata2 = (np.random.random_integers(-30,30,(len(dfdates2)))/10.0) 
df2 = pd.DataFrame(dfdata2, index = dfdates2) 

Do các bước xử lý khác nhau, những dfs kết thúc thay đổi vào df được lập chỉ mục từ năm 1940 đến năm 2015. điều này sẽ tái sản xuất này:

bigdates = pd.date_range('01/01/1940', '01/01/2015', freq = 'MS') 
big1 = pd.DataFrame(index = bigdates) 
big2 = pd.DataFrame(index = bigdates) 
big1 = pd.concat([big1, df1],axis = 1) 
big2 = pd.concat([big2, df2],axis = 1) 

Đây là những gì tôi nhận được khi tôi tương quan với gấu trúc và chuyển đổi một tập dữ liệu:

In [451]: corr_coeff_0 = big1[0].corr(big2[0]) 
In [452]: corr_coeff_0 
Out[452]: 0.030543266378853299 
In [453]: big2_shift = big2.shift(1) 
In [454]: corr_coeff_1 = big1[0].corr(big2_shift[0]) 
In [455]: corr_coeff_1 
Out[455]: 0.020788314779320523 

Và cố gắng scipy:

In [456]: scicorr = scipy.signal.correlate(big1,big2,mode="full") 
In [457]: scicorr 
Out[457]: 
array([[ nan], 
     [ nan], 
     [ nan], 
     ..., 
     [ nan], 
     [ nan], 
     [ nan]]) 

mà theo whos

scicorr    ndarray      1801x1: 1801 elems, type `float64`, 14408 bytes 

Nhưng tôi chỉ muốn có 12 mục. /Edit2

Ý tưởng tôi đã đưa ra, là để thực hiện một thời gian trễ tương quan bản thân mình, như vậy:

corr_coeff_0 = df1['Data'].corr(df2['Data']) 
df1_1month = df1.shift(1) 
corr_coeff_1 = df1_1month['Data'].corr(df2['Data']) 
df1_6month = df1.shift(6) 
corr_coeff_6 = df1_6month['Data'].corr(df2['Data']) 
...and so on 

Nhưng điều này có lẽ là chậm, và tôi có thể cố gắng để phát minh lại bánh xe ở đây. Chỉnh sửa Cách tiếp cận trên dường như hoạt động và tôi đã đưa nó vào vòng lặp, để trải qua tất cả 12 tháng một năm, nhưng tôi vẫn thích phương pháp được tích hợp sẵn.

+0

Nếu bạn chưa từng thấy chúng, hãy xem xét việc sử dụng ['scipy.signal.correlate'] (http://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.correlate .html) và ['scipy.signal.correlate2d'] (http://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.correlate2d.html). Tôi có thể nói rằng việc chuyển đổi sang mảng có nhiều mảng có lẽ là đặt cược tốt nhất của bạn. – wgwz

+0

Tôi đã nhìn thấy những, nhưng tôi muốn tránh đi đến gumpy, bởi vì sau bước này, tôi sẽ phải chuyển đổi trở lại một dataframe, để tính toán thêm. Tôi đoán tôi sẽ cố gắng để phát minh lại bánh xe, sau đó ... –

+0

Đó là một luồng công việc khá phổ biến như xa như tôi biết, chuyển đổi thành numpy và trở lại. Tôi không thấy cần phải ngần ngại làm như vậy. Tôi khuyên bạn nên viết mảng của bạn vào đĩa, vì vậy bạn không lặp lại các chuyển đổi trong mã của mình. Thanh toán 'pd.HDFStore' và' h5py'. Nếu bạn cảm thấy muốn phát minh lại bánh xe, hãy tìm nó. – wgwz

Trả lời

21

Theo như tôi có thể biết, không có phương pháp được tích hợp nào thực hiện chính xác những gì bạn đang yêu cầu.Nhưng nếu bạn nhìn vào mã nguồn cho các phương pháp gấu trúc Dòng autocorr, bạn có thể thấy bạn đã có ý tưởng đúng:

def autocorr(self, lag=1): 
    """ 
    Lag-N autocorrelation 

    Parameters 
    ---------- 
    lag : int, default 1 
     Number of lags to apply before performing autocorrelation. 

    Returns 
    ------- 
    autocorr : float 
    """ 
    return self.corr(self.shift(lag)) 

Vì vậy, một timelagged hàm hiệp phương sai chéo đơn giản sẽ là

def crosscorr(datax, datay, lag=0): 
    """ Lag-N cross correlation. 
    Parameters 
    ---------- 
    lag : int, default 0 
    datax, datay : pandas.Series objects of equal length 

    Returns 
    ---------- 
    crosscorr : float 
    """ 
    return datax.corr(datay.shift(lag)) 

Sau đó, nếu bạn muốn nhìn vào tương quan chéo ở mỗi tháng, bạn có thể làm

xcov_monthly = [crosscorr(datax, datay, lag=i) for i in range(12)] 
+0

Cảm ơn, điều đó sẽ giúp khá nhiều! Hoàn toàn quên rằng việc xây dựng trong tự tương quan về cơ bản là một sự tương quan trễ thời gian. Tôi sẽ thấy nếu tôi có thể làm việc với điều đó để tạo ra một số đầu ra hữu ích hơn chỉ là một danh sách. –

0

có một cách tiếp cận tốt hơn : Bạn có thể tạo một hàm đã di chuyển khung dữ liệu của bạn trước tiên trước khi gọi hàm corr().

Nhận dataframe này như một ví dụ:

d = {'prcp': [0.1,0.2,0.3,0.0], 'stp': [0.0,0.1,0.2,0.3]} 
df = pd.DataFrame(data=d) 

>>> df 
    prcp stp 
0 0.1 0.0 
1 0.2 0.1 
2 0.3 0.2 
3 0.0 0.3 

Chức năng của bạn để chuyển những người khác cột (trừ mục tiêu):

def df_shifted(df, target=None, lag=0): 
    if not lag and not target: 
     return df  
    new = {} 
    for c in df.columns: 
     if c == target: 
      new[c] = df[target] 
     else: 
      new[c] = df[c].shift(periods=lag) 
    return pd.DataFrame(data=new) 

Giả sử rằng mục tiêu của bạn là so sánh prcp (biến lượng mưa) với stp (áp suất khí quyển)

Nếu bạn làm như hiện tại sẽ là:

>>> df.corr() 
     prcp stp 
prcp 1.0 -0.2 
stp -0.2 1.0 

Nhưng nếu bạn chuyển 1 (một) thời gian tất cả các cột khác và giữ mục tiêu (prcp):

df_new = df_shifted(df, 'prcp', lag=-1) 

>>> print df_new 
    prcp stp 
0 0.1 0.1 
1 0.2 0.2 
2 0.3 0.3 
3 0.0 NaN 

Lưu ý rằng bây giờ là stp cột là chuyển lên vị trí tại thời gian, vì vậy nếu bạn gọi cho corr(), sẽ là:

>>> df_new.corr() 
     prcp stp 
prcp 1.0 1.0 
stp 1.0 1.0 

Vì vậy, bạn có thể làm với lag -1, -2, -n !!

Các vấn đề liên quan