例如,对于gr = np.array([5, 4, 3, 5, 2])
和genx = np.array(["femy_gen_m", "my_gen_m", "my_gen_m", "femy_gen_m", "my_gen_m"])
,输出为{'my_gen_m': 3.0, 'femy_gen_m': 5.0}
。暗示使用来自numpy
的平均值
我为老师已经编写的单元测试编写函数,但函数处理速度较慢
附上我的代码如下
from timeit import timeit
import numpy as np
#mycode
def mean_by_redneg(gr, genx):
result = {}
my_gen_m_sum, femy_gen_m_sum = [], []
for index, element in enumerate(genx):
if element == 'my_gen_m':
my_gen_m_sum.append(gr[index])
if element == 'femy_gen_m':
femy_gen_m_sum.append(gr[index])
result['my_gen_m'] = np.asarray(my_gen_m_sum).mean()
result['femy_gen_m'] = np.asarray(femy_gen_m_sum).mean()
return result
#check the function
def test(gr, genx, outp):
ret = mean_by_redneg(np.array(gr), np.array(genx))
assert np.isclose(ret['femy_gen_m'], outp['femy_gen_m'])
assert np.isclose(ret['my_gen_m'], outp['my_gen_m'])
test([5, 4, 3, 5, 2], ["femy_gen_m", "my_gen_m", "my_gen_m", "femy_gen_m", "my_gen_m"], {'my_gen_m': 3.0, 'femy_gen_m': 5.0})
test([1, 0] * 10, ['femy_gen_m', 'my_gen_m'] * 10, {'femy_gen_m': 1, 'my_gen_m': 0})
test(range(100), ['femy_gen_m', 'my_gen_m'] * 50, {'femy_gen_m': 49.0, 'my_gen_m': 50.0})
test(list(range(100)) + [100], ['my_gen_m'] * 100 + ['femy_gen_m'], {'my_gen_m': 49.5, 'femy_gen_m': 100.0})
def bm_test(a, b):
xx = 0
yy = 0
im = 0
fi = 0
for x, y in zip(a, b):
if x != y:
xx += x
yy += x
im += 1
fi += 1
return xx + yy
N = int(1E5)
gr = np.array([1.1] * N + [2.2] * N)
genx = np.array(['my_gen_m'] * N + ['femy_gen_m'] * N)
bm = timeit("assert np.isclose(mean_by_redneg(gr, genx)['my_gen_m'], 1.1)",
"from __main__ import np, mean_by_redneg, gr, genx",
number=1)
reference_bm = timeit("bm_test(gr, genx)",
"from __main__ import bm_test, gr, genx",
number=1)
assert reference_bm > bm * 10, "too slow"
你知道如何更快地完成这项工作吗? p、 谢谢你抽出时间
使用以下功能:
执行时间的比较(使用%timeit)显示:
诚然,对于非常短的测试数据(每个数组中有5项),您的解决方案 速度更快(你的:36µs,我的:52.9µs)
但是如果您需要更长的测试数据(每个数组中有100个项目),那么我的解决方案 更好(你的:99.5µs,我的:62.6µs)
对于更长的源数据,我的解决方案的优势应该更加明显
在
numpy
中实现这一点的矢量化方法比循环代码简单得多。它的核心是:工作原理:
genders == gen
解析为True
和False
的数组,称为“布尔索引”。当grades
被它索引时,它返回grades
的值,这些值对应于索引中的True
位置。因此,当gen
为'Male'
时,grades[genders == gen]
对应于'Male'
s的等级。解析该数组后,使用其.mean()
方法计算平均值,并将其分配给字典由于迭代/索引部分是在作为
numpy
后端的已编译的c
代码中完成的,而不是已解释的python
代码中完成的,因此速度要快得多相关问题 更多 >
编程相关推荐