我有两个列表:
A=[100, 200, 300, 400,......]
B=[50, 110, 150, 210, 250,.........]
我想对B
和A[i]
的每个元素中的列表A[i+1]
中的元素求平均,并通过仅计算边界内的那些元素来计算平均值。
例如,要查找和计算列表A
中100到200之间的所有数字,应仅将列表110 + 150
中的B
加起来,平均值应为(110 + 150) / 2
等等200至300等。
我已经编写了代码,但似乎很冗长。请以较短的方法帮助我。
答案 0 :(得分:2)
from statistics import mean
for lower, upper in zip(A, A[1:]):
average = mean(x for x in B if lower <= x <= upper)
如果其中一个窗口内没有元素,这将引发statistics.StatisticsError
,因为您不能取空列表的平均值。如果要处理这种情况,则需要捕获错误
from statistics import mean, StatisticsError
for lower, upper in zip(A, A[1:]):
try:
average = mean(x for x in B if lower <= x <= upper)
except StatisticsError:
average = None
print(average)
将打印
130
230
None
答案 1 :(得分:1)
到目前为止,所有其他解决方案的时间复杂度为O( mn ),其中A
的大小为 m ,而B
的大小为 n ,因为它对B
中的每对相邻元素进行了A
的迭代。
所以这是O( m + n log m )的一种解决方案,仅对B
进行一次迭代并使用二进制搜索以找到每个数字所在的间隔:
from bisect import bisect_left
def average_bins(a, b):
num_bins = len(a) - 1
sums = [0] * num_bins
counts = [0] * num_bins
for x in b:
i = bisect_left(a, x)
if i > 0 and i <= num_bins:
sums[i-1] += x
counts[i-1] += 1
if i < num_bins and a[i] == x:
sums[i] += x
counts[i] += 1
return [ (s/c if c else None) for s, c in zip(sums, counts) ]
如果知道A
是均匀分布的,则可以通过消除进行二进制搜索的方法将其改进为O( m + n );将i = bisect_left(a, x)
替换为i = math.ceil((x - a[0]) / (a[1] - a[0]))
。
答案 2 :(得分:0)
您可以这样做
avg = []
for j in range(0, len(A)-1):
sum = 0
count = 0
for element in B:
if(element>=A[j] and element<=A[j+1]):
sum+=element
count+=1
if(count!=0):
avg.append(sum/count)
else:
avg.append(None)
答案 3 :(得分:0)
indexOf()
概念是一次获取两个变量:from functools import reduce
for i in range(0,len(a)-1):
lst = list(filter(lambda x: x > a[i]and x < a[i+1],b))
avg = reduce(lambda x,y:x+y,lst) / len(lst)
print(avg)
,a[i]
。
a[i+1]
过滤器功能是过滤掉记录,以便它包含大于lst
且小于a[i]
平均变量的值的列表,实际上将计算总和a[i+1]
中的值,然后除以变量数量以得出平均值。
如果您想进一步了解lambda函数,请告诉我。