首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >大熊猫频次表中的描述性统计

大熊猫频次表中的描述性统计
EN

Stack Overflow用户
提问于 2016-09-18 14:52:49
回答 3查看 3.5K关注 0票数 2

我有一个测试分数频次表:

代码语言:javascript
复制
score    count
-----    -----
  77      1105
  78       940
  79      1222
  80      4339
etc

我想显示基本的统计数据和一个方格图的样本,这是总结的频率表。(例如,上述示例的平均值为79.16,中位数为80)。

在潘达斯有办法这样做吗?我所看到的所有例子都假设了一个单独案例的表格。

我想我可以生成一个个人分数的列表,像这样--

代码语言:javascript
复制
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不同的问题,它是关于将权重应用于个别情况的。)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-09-18 15:47:59

下面是一个小函数,用于计算频率分布的统计数据:

代码语言:javascript
复制
# 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

演示:

代码语言:javascript
复制
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,也没有进行适当的测试。

票数 5
EN

Stack Overflow用户

发布于 2016-09-18 17:52:38

在我最初的问题中,我说我不想从频度表中重构原始值,但只要它适合记忆,我现在认为我将走这条路,特别是因为我的实际用例涉及更多列。

如果有人感兴趣,下面是我的函数,将一个频率表转换为案例。

代码语言:javascript
复制
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
票数 2
EN

Stack Overflow用户

发布于 2019-03-11 01:50:36

你可以这样做:

  1. 使用groupby,您可以划分“得分”列。
  2. 你可以加上“得分”次数。
  3. sum(add)是列表列表。因此,使用itertools.chain,您可以将其列成扁平列表。
  4. 使用pd.Series(),可以使用.describe()
代码语言:javascript
复制
    import itertools
    sum_add = []
    for idx,grp in df.groupby('score'):
        sum_add.append((list(grp['score']) * grp['count'].iloc[0]) )
    pd.Series(list(itertools.chain.from_iterable(sum_add))).describe()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39558988

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档