2017-04-12 47 views
0

一个新的专栏中,我有这样的应用列操作,以获得在大熊猫

ID 8-Jan 15-Jan 22-Jan 29-Jan 5-Feb 12-Feb LowerBound UpperBound 
001 618 720 645  573  503  447  -    - 
002 62  80  67  94  81  65  -    -  
003 32  10  23  26  26  31  -    - 
004 22  13  1  28  19  25  -    - 
005 9  7  9  6  8  4  -    - 

我想创建一个使用95%的置信区间下限,并为每个产品上界两列中的数据。我知道写这遍历每个产品ID

import numpy as np 
import scipy as sp 
import scipy.stats 

# Method copied from http://stackoverflow.com/questions/15033511/compute-a-confidence-interval-from-sample-data 
def mean_confidence_interval(data, confidence=0.95): 
    a = 1.0*np.array(data) 
    n = len(a) 
    m, se = np.mean(a), scipy.stats.sem(a) 
    h = se * sp.stats.t._ppf((1+confidence)/2., n-1) 
    return m-h, m+h 

是否有熊猫的有效方式或(一个衬垫之类的话)功能的手动方式?

回答

2

当然,你想要df.apply。请注意,您需要修改mean_confidence_interval以返回pd.Series([m-h, m+h])

df[['LowerBound','UpperBound']] = df.apply(mean_confidence_interval, axis=1) 
0

既然你已经创建了一个函数计算的置信区间,只需将其应用到你每行数据:

def mean_confidence_interval(data): 
    confidence = 0.95  
    m = data.mean() 
    se = scipy.stats.sem(data) 
    h = se * sp.stats.t._ppf((1 + confidence)/2, data.shape[0] - 1) 
    return pd.Series((m - h, m + h)) 

interval = df.apply(mean_confidence_interval, axis=1) 
interval.columns = ("LowerBound", "UpperBound") 
pd.concat([df, interval],axis=1) 
2

的均值的标准差是非常简单的计算,所以你可以很容易地矢量化这个:

import scipy.stats as ss 
df.mean(axis=1) + ss.t.ppf(0.975, df.shape[1]-1) * df.std(axis=1)/np.sqrt(df.shape[1]) 

会给你的上限。使用- ss.t.ppf作为下限。

此外,熊猫似乎有一个sem method。如果你有一个大的数据集,我不建议在行上使用apply。这很慢。以下是一些时机:

df = pd.DataFrame(np.random.randn(100, 10)) 

%timeit df.apply(mean_confidence_interval, axis=1) 
100 loops, best of 3: 18.2 ms per loop 

%%timeit 
dist = ss.t.ppf(0.975, df.shape[1]-1) * df.sem(axis=1) 
mean = df.mean(axis=1) 
mean - dist, mean + dist 
1000 loops, best of 3: 598 µs per loop 
+1

这真的很聪明!它必须也相当快... – MaxU

+1

@MaxU Thanks.It似乎像大熊猫也有一个方法。它比应用耶更快。 – ayhan