计算值出现在值范围内的次数

时间:2019-04-15 11:38:11

标签: python python-3.x

如何输出一个列表,该列表计算并显示不同值适合某个范围的次数?

根据以下示例,由于存在3个专业得分x = [0, 3, 2, 1, 0],2个冠军得分(11, 24, 44)和1个国王得分(101, 888),因此输出为(1234)。 / p>

- P1 = 11 
- P2 = 24
- P3 = 44
- P4 = 101
- P5 = 1234
- P6 = 888

totalsales = [11, 24, 44, 101, 1234, 888]

以下是与销售额相对应的排名:

Sales___________________Ranking
0-10____________________Noob
11-100__________________Pro
101-1000________________Champion
1001-10000______________King
100001 - 200000__________Lord

6 个答案:

答案 0 :(得分:1)

这是一种方法,假设您的值是整数且范围不重叠。

from collections import Counter

# Ranges go to end + 1
score_ranges = [
    range(0, 11),         # Noob
    range(11, 101),       # Pro
    range(101, 1001),     # Champion
    range(1001, 10001),   # King
    range(10001, 200001)  # Lord
]
total_sales = [11, 24, 44, 101, 1234, 888]

# This counter counts how many values fall into each score range (by index).
# It works by taking the index of the first range containing each value (or -1 if none found).
c = Counter(next((i for i, r in enumerate(score_ranges) if s in r), -1) for s in total_sales)
# This converts the above counter into a list, taking the count for each index.
result = [c[i] for i in range(len(score_ranges))]
print(result)
# [0, 3, 2, 1, 0]

答案 1 :(得分:0)

一般而言,作业不应发布在stackoverflow上。因此,实现方法仅取决于如何解决这个问题。

遍历totalsales列表,并检查每个数字是否在range(start,stop)中。然后,为每个匹配的检查增量在结果列表中的每个类别中增加一个(但是使用dict来存储结果可能更合适)。

答案 2 :(得分:0)

如果销售到排名的映射始终遵循对数曲线,则可以使用math.log10collections.Counter在线性时间内计算所需的输出。使用偏移量0.5和abs函数来处理0和1的销量:

from collections import Counter
from math import log10
counts = Counter(int(abs(log10(abs(s - .5)))) for s in totalsales)
[counts.get(i, 0) for i in range(5)]

这将返回:

[0, 3, 2, 1, 0]

答案 3 :(得分:0)

您可以使用collections.Counterdict

from collections import Counter

totalsales = [11, 24, 44, 101, 1234, 888]

ranking = {
    0: 'noob',
    10: 'pro',
    100: 'champion',
    1000: 'king',
    10000: 'lord'
}

c = Counter()
for sale in totalsales:
    for k in sorted(ranking.keys(), reverse=True):
        if sale > k:
            c[ranking[k]] += 1
            break

或者作为两线客制(该想法的积分@jdehesa):

thresholds = sorted(ranking.keys(), reverse=True)
c = Counter(next((ranking[t] for t in thresholds if s > t)) for s in totalsales)

答案 4 :(得分:0)

这里是不使用诸如numpycollections之类的模块的可能解决方案:

totalsales = [11, 24, 44, 101, 1234, 888]
bins = [10, 100, 1000, 10000, 20000]
output = [0]*len(bins)

for s in totalsales:
    slot = next(i for i, x in enumerate(bins) if s <= x)
    output[slot] += 1

output

>>> [0, 3, 2, 1, 0]

答案 5 :(得分:0)

在这里,我使用了数据框的功能来存储值,然后使用bin和cut将值分组为正确的类别。将值计数提取到列表中。 让我知道是否可以。

import pandas as pd
import numpy
df = pd.DataFrame([11, 24, 44, 101, 1234, 888], columns=['P'])# Create dataframe

bins = [0, 10, 100, 1000, 10000,  200000]
labels = ['Noob','Pro', 'Champion', 'King', 'Lord']
df['range'] = pd.cut(df.P, bins, labels = labels)
df

输出:

P   range
0   11  Pro
1   24  Pro
2   44  Pro
3   101 Champion
4   1234    King
5   888 Champion

最后,获取值计数。使用:

my = df['range'].value_counts().sort_index()#this counts to the number of occurences
output=map(int,my.tolist())#We want the output to be integers
output

以下结果:

[0, 3, 2, 1, 0]