我有一个测试分数频次表:
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不同的问题,它是关于将权重应用于个别情况的。)
发布于 2016-09-18 15:47:59
下面是一个小函数,用于计算频率分布的统计数据:
# 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,也没有进行适当的测试。
发布于 2016-09-18 17:52:38
在我最初的问题中,我说我不想从频度表中重构原始值,但只要它适合记忆,我现在认为我将走这条路,特别是因为我的实际用例涉及更多列。
如果有人感兴趣,下面是我的函数,将一个频率表转换为案例。
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发布于 2019-03-11 01:50:36
你可以这样做:
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()https://stackoverflow.com/questions/39558988
复制相似问题