在Python的NumPy库中,np.remainder
和 np.mod
都是用来计算除法的余数,但它们在处理余数时的行为有所不同,尤其是在处理负数的除法时。
np.remainder
np.remainder
函数按照向量操作,计算数组中每个元素除以另一个数组相应元素后的余数。余数的符号与被除数的符号相同。也就是说,如果被除数是负数,计算出的余数也将是负数。
import numpy as np
x = np.array([-3, -2, -1, 0, 1, 2, 3])
y = 2
print(np.remainder(x, y)) # 输出: [-1. -0.5 -0.5 0. 1.5 1.5 1.5]
np.mod
np.mod
函数也是计算除法的余数,但它总是返回非负的余数。无论被除数是正数还是负数,np.mod
都会返回一个0到除数之间的余数,如果余数是负数,它会被调整到正数范围内。
x = np.array([-3, -2, -1, 0, 1, 2, 3])
y = 2
print(np.mod(x, y)) # 输出: [1. 0. 1. 0. 1. 0. 1.]
使用场景
- 使用
np.remainder
当你想要余数保持与原始被除数相同的符号。 - 使用
np.mod
当你想要一个始终非负的余数,这在某些数学运算或统计分析中可能更有用。
注意
np.remainder
和np.mod
的行为与Python内置的%
操作符不同。Python的%
操作符会根据被除数的符号返回正或负的余数,而np.mod
总是返回非负的余数。- 当处理非常大的数组或矩阵时,使用NumPy的函数通常比使用Python的内置操作符更高效。
选择 np.remainder
还是 np.mod
取决于你的具体需求和期望的余数行为。如果你需要数学上的“remainder”(可能为负),使用 np.remainder
;如果你需要一个始终非负的“modulo”结果,使用 np.mod
。
统计全班的成绩
假设一个团队里有 5 名学员,成绩如下表所示。你可以用 NumPy 统计下这些人在语文、英语、数学中的平均成绩、最小成绩、最大成绩、方差、标准差。然后把这些人的总成绩排序,得出名次进行成绩输出。
import numpy as np
persontype = np.dtype({
'names': ['name', 'language', 'english', 'math'],
'formats': ['U32', 'f', 'f', 'f'],
})
peoples = np.array(
[
('ZhangFei', 66, 65, 30),
('GuanYv', 95, 85, 98),
('ZhaoYun', 93, 92, 96),
('HuangZhong', 90, 88, 77),
('DianWei', 80, 90, 90),
],
dtype=persontype,
)
dash_line = '=' * 40
# 各科平均、最小、最大,方差,标准差
tfuncs = [np.average, np.min, np.max, np.var, np.std]
for tfunc in tfuncs:
for tname in persontype.names[1:]:
print(f'subject: {tname:>8}, {tfunc.__name__} score: {tfunc(peoples[:][tname]):.2f}')
print(dash_line)
# 各科排名
for tname in persontype.names[1:]:
rank = np.sort(peoples, order=tname)[::-1][['name', tname]]
for i, (name, score) in enumerate(zip(rank['name'], rank[tname])):
print(f'subject: {tname:>8}, rank: {i+1}, name: {name:>10}, score: {score:.2f}')
print(dash_line)
# 总分排名
total_scores = np.zeros_like(peoples['language'])
for tname in persontype.names[1:]:
total_scores += peoples[tname]
sorted_indices = np.argsort(total_scores)[::-1]
sorted_total_scores = total_scores[sorted_indices]
sorted_names = peoples['name'][sorted_indices]
for i, (name, total_score) in enumerate(zip(sorted_names, sorted_total_scores)):
print(f'rank: {i+1}, name: {name:>10}, total_score: {total_score:.2f}')
subject: language, average score: 84.80
subject: english, average score: 84.00
subject: math, average score: 78.20
subject: language, min score: 66.00
subject: english, min score: 65.00
subject: math, min score: 30.00
subject: language, max score: 95.00
subject: english, max score: 92.00
subject: math, max score: 98.00
subject: language, var score: 114.96
subject: english, var score: 95.60
subject: math, var score: 634.56
subject: language, std score: 10.72
subject: english, std score: 9.78
subject: math, std score: 25.19
========================================
subject: language, rank: 1, name: GuanYv, score: 95.00
subject: language, rank: 2, name: ZhaoYun, score: 93.00
subject: language, rank: 3, name: HuangZhong, score: 90.00
subject: language, rank: 4, name: DianWei, score: 80.00
subject: language, rank: 5, name: ZhangFei, score: 66.00
subject: english, rank: 1, name: ZhaoYun, score: 92.00
subject: english, rank: 2, name: DianWei, score: 90.00
subject: english, rank: 3, name: HuangZhong, score: 88.00
subject: english, rank: 4, name: GuanYv, score: 85.00
subject: english, rank: 5, name: ZhangFei, score: 65.00
subject: math, rank: 1, name: GuanYv, score: 98.00
subject: math, rank: 2, name: ZhaoYun, score: 96.00
subject: math, rank: 3, name: DianWei, score: 90.00
subject: math, rank: 4, name: HuangZhong, score: 77.00
subject: math, rank: 5, name: ZhangFei, score: 30.00
========================================
rank: 1, name: ZhaoYun, total_score: 281.00
rank: 2, name: GuanYv, total_score: 278.00
rank: 3, name: DianWei, total_score: 260.00
rank: 4, name: HuangZhong, total_score: 255.00
rank: 5, name: ZhangFei, total_score: 161.00