我想在向量a
中计算并保存大于某个值t
的数组元素的数量。我想为不同的t
做这个。
例如
我的矢量:c=[0.3 0.2 0.3 0.6 0.9 0.1 0.2 0.5 0.3 0.5 0.7 0.1]
我想计算c
的元素数量大于t=0.9
,而不是t=0.8
而不是t=0.7
等...我想要保存计算向量中每个不同的t值
我的代码是(不工作):
for t in range(0,10,1):
for j in range(0, len(c)):
if c[j]>t/10:
a.append(sum(c[j]>t))
我的矢量a应该是维度10,但它不是!
任何人都可以帮助我吗?
答案 0 :(得分:2)
我创建了一个遍历数组的函数,只要值大于提供的阈值
就会计数c=[0.3, 0.2, 0.3, 0.6, 0.9, 0.1, 0.2, 0.5, 0.3, 0.5, 0.7, 0.1]
def num_bigger(threshold):
count = 0
for num in c:
if num > threshold:
count +=1
return count
thresholds = [x/10.0 for x in range(10)]
for thresh in thresholds:
print thresh, num_bigger(thresh)
请注意,函数检查严格更大,这就是为什么,例如,当阈值为.9时结果为0。
答案 1 :(得分:2)
您的代码几乎没有问题。
我的矢量a应该是维度10,但它不是!
那是因为你不会在列表中追加10个元素。看看你的逻辑。
for t in range(0,10,1):
for j in range(0, len(c)):
if c[j]>t/10:
a.append(sum(c[j]>t))
对于每个阈值t
,您一次迭代c
中的所有12个项目,然后将某些内容附加到列表中。总的来说,你得到120件物品。你应该做的是(伪代码):
for each threshold:
count = how many elements in c are greater than threshold
a.append(count)
numpy.where()
为您提供满足条件的数组中的索引,因此您只需计算每次获得的索引数。我们将完全解决这个问题。
另一个潜在的错误是t/10
,它在Python 2中是整数除法,并且对于所有阈值都将返回0。正确的方法是使用t/10.
强制浮动除法。如果您使用的是Python 3,则默认情况下会进行浮动分割,因此这可能不是问题。请注意,您执行c[j] > t
,其中t
介于0到10之间。总体而言,您的c[j] > t
逻辑错误。您希望对所有元素使用计数器,就像其他答案向您展示的那样,或者将其全部折叠为单行列表理解。
最后,这是一个充分利用numpy的解决方案。
import numpy as np
c = np.array([0.3, 0.2, 0.3, 0.6, 0.9, 0.1, 0.2, 0.5, 0.3, 0.5, 0.7, 0.1])
thresh = np.arange(0, 1, 0.1)
counts = np.empty(thresh.shape, dtype=int)
for i, t in enumerate(thresh):
counts[i] = len(np.where(c > t)[0])
print counts
输出:
[12 10 8 5 5 3 2 1 1 0]
让numpy处理引擎盖下的循环比Python级循环更快。为了演示:
import timeit
head = """
import numpy as np
c = np.array([0.3, 0.2, 0.3, 0.6, 0.9, 0.1, 0.2, 0.5, 0.3, 0.5, 0.7, 0.1])
thresh = np.arange(0, 1, 0.1)
"""
numpy_where = """
for t in thresh:
len(np.where(c > t)[0])
"""
python_loop = """
for t in thresh:
len([element for element in c if element > t])
"""
n = 10000
for test in [numpy_where, python_loop]:
print timeit.timeit(test, setup=head, number=n)
在我的计算机上会产生以下时间。
0.231292377372
0.321743753994
答案 2 :(得分:1)
你的问题在这里:
if c[j]>t/10:
请注意,t和10都是整数,因此您执行整数除法。 变化最小的最简单的解决方案是将其更改为:
if c[j]>float(t)/10:
强制浮动分割
所以整个代码看起来像这样:
a = []
c = [0.3, 0.2, 0.3, 0.6, 0.9, 0.1, 0.2, 0.5, 0.3, 0.5, 0.7, 0.1]
for i in range(10): #10 is our 1.0 change it to 9 if you want to iterate to 0.9
sum = 0
cutoff = float(i)/10
for ele in c:
if ele <= cutoff:
sum += ele
a.append(sum)
print(len(a)) # prints 10, the numbers from 0.0 - 0.9
print(a) # prints the sums going from 0.0 cutoff to 1.0 cutoff
答案 3 :(得分:1)
你必须除t / 10.0所以结果是小数,t / 10的结果是一个整数
a = []
c=[0.3, 0.2, 0.3, 0.6, 0.9, 0.1, 0.2, 0.5, 0.3, 0.5, 0.7, 0.1]
for t in range(0,10,1):
count = 0
for j in range(0, len(c)):
if c[j]>t/10.0:
count = count+1
a.append(count)
for t in range(0,10,1):
print(str(a[t]) + ' elements in c are bigger than ' + str(t/10.0))
输出:
12 elements in c are bigger than 0.0
10 elements in c are bigger than 0.1
8 elements in c are bigger than 0.2
5 elements in c are bigger than 0.3
5 elements in c are bigger than 0.4
3 elements in c are bigger than 0.5
2 elements in c are bigger than 0.6
1 elements in c are bigger than 0.7
1 elements in c are bigger than 0.8
0 elements in c are bigger than 0.9
您可以查看测试here
答案 4 :(得分:1)
如果您简化代码错误,则无法隐藏地方!
c=[0.3, 0.2, 0.3, 0.6, 0.9, 0.1, 0.2, 0.5, 0.3, 0.5, 0.7, 0.1]
a=[]
for t in [x/10 for x in range(10)]:
a.append((t,len([x for x in c if x>t])))
a
[(0.0, 12),
(0.1, 10),
(0.2, 8),
(0.3, 5),
(0.4, 5),
(0.5, 3),
(0.6, 2),
(0.7, 1),
(0.8, 1),
(0.9, 0)]
甚至是这种单行
[(r/10,len([x for x in c if x>r/10])) for r in range(10)]
答案 5 :(得分:1)
这取决于数组的大小,但您当前的解决方案具有O(m*n)
复杂度,m
是要测试的值的数量,n
是数组的大小。首先使用O((m+n)*log(n))
对数组进行排序,然后使用二进制搜索在O(n*log(n))
中查找m
值,最好使用O(m*log(n))
。使用numpy和您的示例c
列表,这将是:
>>> c
[0.3, 0.2, 0.3, 0.6, 0.9, 0.1, 0.2, 0.5, 0.3, 0.5, 0.7, 0.1]
>>> thresholds = np.linspace(0, 1, 10, endpoint=False)
>>> thresholds
array([ 0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])
>>> len(c) - np.sort(c).searchsorted(thresholds, side='right')
array([12, 10, 8, 5, 5, 3, 2, 1, 1, 0])