2015-10-17 49 views
2

比方說,我有x-y數據樣本按x值排序。我將以熊貓爲例,但當然,我會非常滿意Numpy/Scipy-only解決方案。「x-value-window」的numpy或Pandas功能意味着還是其他統計數據?

In [24]: pd.set_option('display.max_rows', 10) 

In [25]: df = pd.DataFrame(np.random.randn(100, 2), columns=['x', 'y']) 

In [26]: df = df.sort('x') 

In [27]: df 
Out[27]: 
     x   y 
13 -3.403818 0.717744 
49 -2.688876 1.936267 
74 -2.388332 -0.121599 
52 -2.185848 0.617896 
90 -2.155343 -1.132673 
..  ...  ... 
65 1.736506 -0.170502 
0 1.770901 0.520490 
60 1.878376 0.206113 
63 2.263602 1.112115 
33 2.384195 -1.877502 

[100 rows x 2 columns] 

現在,我想要一種「窗口」或「離散化」它並獲得每個窗口的統計數據。但我不想做熊貓moving-window functions,因爲它們按行定義窗口。我想通過一個x值範圍來定義窗口,因此是「x值窗口」。具體地,讓我們定義用2個參數的每個x值窗口:在該示例中每個窗口

    1. 中心的x值,讓我們說,我想X = 0.0 + 0.4 * k個對所有正或負ķ
    2. 從而-3.2,-2.8,-2.4,...,1.6,2.0,2.4
  • 寬度各窗口的
      在此
    • EXA因此,示例窗口將爲[-3.2-0.25,-3.2 + 0.25],[-2.8-0.25,-2.8 + 0.25],...,[2.4- 0.25,2.4 + 0.25]
    • 說明該窗口重疊,其意欲
  • 已經如此限定的窗口,我想詢問是否有能產生以下的數據幀的函數(或numpy陣列):

    x   y 
    -3.2 mean of y-values in x-value-window centered at -3.2 
    -2.8 mean of y-values in x-value-window centered at -2.8 
    -2.4 mean of y-values in x-value-window centered at -2.4 
    ...  ... 
    1.6 mean of y-values in x-value-window centered at 1.6 
    2.0 mean of y-values in x-value-window centered at 2.0 
    2.4 mean of y-values in x-value-window centered at 2.4 
    

    有沒有什麼會做對我來說?或者我必須完全推出自己的(可能在一個非常緩慢的Python循環,而不是快速的numpy或熊貓代碼)?

    額外1:這將是即使有對加權窗口更好的支持(例如由熊貓的rolling_window function的支持),但當然在這種情況下,權重將不會根據樣本的行多遠是從中心行的窗口,而是樣本的x值離x值窗口的中心有多遠。

    額外2:如果支持x值窗口上的平均值以外的其他統計信息,例如: (a)每個x值窗口中的y值的方差或(b)落入每個x值窗口內的樣本數量的計數。

    回答

    0

    我首先創建一個以零爲中心的x值範圍。此範圍足夠寬,以便最小值減去寬度,最大值加上寬度將捕獲所有x值。

    然後我遍歷這個x值的範圍,其中k作爲步長。在每個點上,我使用loc來捕獲位於選定的xy值加上和減去寬度。然後計算這些選定值的平均值。這些值用於創建result數據幀。

    import math 
    import numpy as np 
    import pandas as pd 
    
    k = .4 
    w = .5 
    np.random.seed(0) 
    df = pd.DataFrame(np.random.randn(100, 2), columns=['x', 'y']) 
    
    x_range = np.arange(math.floor((df.x.min() + w)/k) * k, 
            k * (math.ceil((df.x.max() - w)/k) + 1), k) 
    
    result = pd.DataFrame((df.loc[df.x.between(x - w, x + w), 'y'].mean() for x in x_range), 
             index=x_range, columns=['y_mean']) 
    result.index.name = 'centered_x' 
    >>> result 
           y_mean 
    centered_x    
    -2.400000e+00 0.653619 
    -2.000000e+00 0.733606 
    -1.600000e+00 0.576594 
    -1.200000e+00 0.150462 
    -8.000000e-01 0.065884 
    -4.000000e-01 0.022925 
    -8.881784e-16 0.211693 
    4.000000e-01 0.057527 
    8.000000e-01 -0.141970 
    1.200000e+00 0.233695 
    1.600000e+00 0.203570 
    2.000000e+00 0.306409 
    2.400000e+00 0.576789 
    
    +0

    感謝您編寫答案!這似乎更接近於「滾動我自己的」而不是「支持的功能」。 – eng

    +0

    這不是我正在尋找的答案(我可以在沒有編寫代碼的幫助下推出自己的答案),但是我給了信用,因爲你是唯一花時間寫答案的人。 – eng