我有一个测试成绩的频率表:
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
-但我希望避免这种情况;真实的非玩具数据集中的总频率高达十亿。
任何帮助表示赞赏。
这是一个用于计算频率分布的描述统计量的小函数:
# 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,并且未经适当测试。