python - 百分位数计算:我可以将此 for 循环转换为向量运算吗?
问题描述
我有一个分数数组作为输入,我想输出一个数组,每个分数都附有百分位数。而且我有意识地不使用stats.percentileofscore()
,因为我正在使用它作为学习 numpy 数据处理和操作的机会。
给定输入:
math_scores = np.array([51, 61, 45, 72, 78, 61, 84, 50, 42, 57])
我希望的输出print(scores_with_percentile)
是:
[[51 35]
[61 60]
[45 15]
[72 75]
[78 85]
[61 60]
[84 95]
[50 25]
[42 5]
[57 45]]
计算基于此维基百科页面中的公式
我写了以下代码:
math_scores = np.array([51, 61, 45, 72, 78, 61, 84, 50, 42, 57])
data_size = math_scores.shape
percentile_col = np.zeros(data_size, dtype=int)
for i, score in enumerate(math_scores):
count = (math_scores < score).sum()
freq = (math_scores == score).sum()
percentile_col[i] = (count + (0.5*freq))*100/data_size
scores_with_percentile = np.stack((math_scores, percentile_col), axis=1)
print(scores_with_percentile)
这对我来说很好,但我确信它不是很有效,因为我才开始熟悉 numpy。我想知道是否可以通过使用一些向量操作来避免 for 循环。也欢迎任何其他改进代码的建议。
解决方案
每当我们想要遍历同一个 numpy 数组的元素时,我们可以在新轴上创建另一个数组。所以我们可以在二维数组上使用 numpy 的向量化函数。
math_scores = np.array([51, 61, 45, 72, 78, 61, 84, 50, 42, 57])
data_size = math_scores.shape
count = np.less(math_scores, math_scores[:,np.newaxis]).sum(axis=1)
freq = np.equal(math_scores,math_scores[:,np.newaxis]).sum(axis=1)
percentile_col = (count + (0.5*freq))*100/data_size
scores_with_percentile = np.stack((math_scores, percentile_col), axis=1)
print(scores_with_percentile)
[[51. 35.]
[61. 60.]
[45. 15.]
[72. 75.]
[78. 85.]
[61. 60.]
[84. 95.]
[50. 25.]
[42. 5.]
[57. 45.]]
推荐阅读
- c# - SerialDataReceivedEventHandler 没有被触发
- windows - 从 powershell 卸载设备
- eclipse - DBeaver 内容辅助颜色
- python - 从应用于初始数据帧的多个条件构建数据帧:这种情况适用于 pandas 而不是 pyspark?
- sql - sql作业停止重复
- swift - Xcode:不尊重水平约束?
- java - Android AlertDialogs 未在特定活动中显示按钮
- reactjs - 使用 Reactjs 将道具传递给功能组件时,如果语句不起作用?
- eclipse - 硒元素不可交互错误,没有反馈
- unit-testing - 如何在多种配置中运行相同的 xunit.net 测试套件?