2016-09-18 91 views
1

我的考試成績頻數表:描述統計在熊貓

score count 
----- ----- 
    77  1105 
    78  940 
    79  1222 
    80  4339 
etc 

我想說明的基本統計信息和它是由頻率表總結了樣品的箱線圖。 (例如,上面例子的平均值是79.16,中位數是80.)

有沒有辦法在熊貓中做到這一點?我見過的所有例子都假設了一個個案的表格。

我想我可以生成個人得分列表,像這樣 -

In [2]: s = pd.Series([77] * 1105 + [78] * 940 + [79] * 1222 + [80] * 4339) 
In [3]: s.describe() 
Out[3]: 
count 7606.000000 
mean  79.156324 
std   1.118439 
min  77.000000 
25%  78.000000 
50%  80.000000 
75%  80.000000 
max  80.000000 
dtype: float64 

- 但我希望能避免;真正的非玩具數據集中的總頻率在十億以上。

任何幫助表示讚賞。

(我認爲這是從Using describe() with weighted data一個不同的問題,這是關於申請權重個案。)

+0

的可能的複製http://stackoverflow.com/questions/17689099/using-describe-with-weighted-data –

+0

我認爲這是* *同我聯繫的問題:你想加權描述「count」列給出的「score」列的統計信息。唉,我不認爲這個問題有一個令人滿意的答案。 –

+0

我同意他們要求非常類似的事情,但我不知道SAS proc是如何工作的,所以我會在這裏發佈我的答案,因爲它可能不滿足這些要求。 – ayhan

回答

3

這裏有一個小的函數,計算頻率分佈decriptive統計:

# from __future__ import division (for Python 2) 
def descriptives_from_agg(values, freqs): 
    values = np.array(values) 
    freqs = np.array(freqs) 
    arg_sorted = np.argsort(values) 
    values = values[arg_sorted] 
    freqs = freqs[arg_sorted] 
    count = freqs.sum() 
    fx = values * freqs 
    mean = fx.sum()/count 
    variance = ((freqs * values**2).sum()/count) - mean**2 
    variance = count/(count - 1) * variance # dof correction for sample variance 
    std = np.sqrt(variance) 
    minimum = np.min(values) 
    maximum = np.max(values) 
    cumcount = np.cumsum(freqs) 
    Q1 = values[np.searchsorted(cumcount, 0.25*count)] 
    Q2 = values[np.searchsorted(cumcount, 0.50*count)] 
    Q3 = values[np.searchsorted(cumcount, 0.75*count)] 
    idx = ['count', 'mean', 'std', 'min', '25%', '50%', '75%', 'max'] 
    result = pd.Series([count, mean, std, minimum, Q1, Q2, Q3, maximum], index=idx) 
    return result 

一個演示:

np.random.seed(0) 

val = np.random.normal(100, 5, 1000).astype(int) 

pd.Series(val).describe() 
Out: 
count 1000.000000 
mean  99.274000 
std   4.945845 
min  84.000000 
25%  96.000000 
50%  99.000000 
75%  103.000000 
max  113.000000 
dtype: float64 

vc = pd.value_counts(val) 
descriptives_from_agg(vc.index, vc.values) 

Out: 
count 1000.000000 
mean  99.274000 
std   4.945845 
min  84.000000 
25%  96.000000 
50%  99.000000 
75%  103.000000 
max  113.000000 
dtype: float64 

請注意,這不處理NaN和未正確測試。

+0

謝謝!你的快速反應爲我節省了幾個小時,試圖找到一種內置的方式來做到這一點。 – wleftwich

1

在我原來的問題中,我說我不想重建頻率表中的原始值,但只要它適合內存我現在想我會走這條路線,特別是因爲我的實際使用情況涉及更多的列。

如果有人有興趣,這裏是我的功能轉換頻率表成案例。

In [5]: def freqs2cases(df, freq_col, cases_cols): 
    ...:  def itcases(): 
    ...:   for i, row in df.iterrows(): 
    ...:    for j in range(int(row[freq_col])): 
    ...:     yield row[cases_cols] 
    ...:  return pd.DataFrame(itcases()) 
    ...: 

In [8]: freq_df 
Out[8]: 
    course score freq 
0 math  75  3 
1 math  81  4 
2 chem  92  2 
3 chem  66  3 

In [9]: freqs2cases(freq_df, 'freq', ['course', 'score']) 
Out[9]: 
    course score 
0 math  75 
0 math  75 
0 math  75 
1 math  81 
1 math  81 
1 math  81 
1 math  81 
2 chem  92 
2 chem  92 
3 chem  66 
3 chem  66 
3 chem  66