在python代码中如何将一个序列号分割成区间?

2024-10-01 22:28:38 发布

您现在位置:Python中文网/ 问答频道 /正文

Cut将x的范围划分为区间,并根据x中的区间对x中的值进行编码,我可以用R中的Cut函数得到一个小的群,我怎么做呢 在python代码中工作?在

raw_data='
82   68   86   94   89   63   77   76   84    89
75   78   81   82   76   99   80   84   89    88
60   83   72   83   85   56   86   68   75   100
90   84   75   86   74   77   95   63   80    76
100   43  76   81   79   74   96   52   69    86'
data<-scan(textConnection(raw_data)) 
table(cut(data,include.lowest=TRUE,right=FALSE,breaks=c(0,60,70,80,90,100))

输出为:

^{pr2}$

Tags: 函数代码righttrue编码datascanraw
3条回答

我提议制定以下准则:

raw_data='''
82   68   86   94   89   63   77   76   84    89
75   78   81   82   76   99   80   84   89    88
60   83   72   83   85   56   86   68   75   100
90   84   75   86   74   77   95   63   80    76
100   43  76   81   79   74   96   52   69    86'''
tu = (0,60,70,80,90,100)

print raw_data
print tu

from collections import OrderedDict
tu0 = tu[0]
tuL = tu[-1]
tuF = tu[1:]
d = OrderedDict((tu[i], [tu[i-1:i+1]])
                for i in xrange(1,len(tu)))

for x in map(int,raw_data.split()):
    if x>=tu0:
        if x==tuL:
            d[tuL].append(x)
        else:
            for lim in tuF:
                if x<lim:
                    d[lim].append(x)
                    break
print
print '\n'.join('%-15s%s' % (d[k][0],len(d[k])-1) for k in d)

结果

^{pr2}$

一。在

编辑

我对算法中的这些ifforelse和{}都不满意。
所以我给出了一个新的代码,我认为这是一个改进,因为它更简短、更清晰。我觉得它也更快,但我没有测试速度。在

困难在于,当原始数据中的一个数字等于极限序列tu = (0,60,70,80,90,100)的最后一个值(样本中为100),这个数字必须被计算为属于最后一个跨度,这里是样本中的[90,100](数学表示法),而前面的跨度如[0,60[[60,70[。。。不包括上限。
但是我最终找到了正确的测试x==tuLast==lim来保存这个特定的情况,然后能够使用一个生成器来代替以前可怕的算法,它有几个测试if和一个循环。在

以下代码在Python3中是可执行的。在

raw_data='''
82   68   86   94   89   63   77   76   84    89
75   78   81   82   76   99   80   84   89    88
60   83   72   83   85   56   86   68   75   100
90   84   75   86   74   77   95   63   80    76
100   43  76   81   79   74   96   52   69    86'''
tu = [0,60,70,80,90,100]
print( 'raw_data :%s\n\ntu :\n%s' % (raw_data,tu),'\n' )

tu0, tuLast = tu[0], tu[-1]
tu_from1 = tu[1:]
from collections import OrderedDict
d = OrderedDict( (two[1],[two]) for two in zip(tu, tu_from1) )

print ('OrderedDictionary , before:\n%s'
       % '\n'.join('key:%3s   value:%s'  % item for item in d.items()))

# the core of the code is here:
for x in (x for x in map(int,raw_data.split()) if x>=tu0):
    d[next(lim for lim in tu_from1
           if x<lim or x==tuLast==lim)].append(x)

print ('\nOrderedDictionary , after:\n%s'
       % '\n'.join('key:%3s   value:%s'  % item for item in d.items()),'\n')

print( '\n'.join('%-15s%s' % (v[0],len(v)-1) for v in d.values()) )

结果

raw_data :
82   68   86   94   89   63   77   76   84    89
75   78   81   82   76   99   80   84   89    88
60   83   72   83   85   56   86   68   75   100
90   84   75   86   74   77   95   63   80    76
100   43  76   81   79   74   96   52   69    86

tu :
[0, 60, 70, 80, 90, 100] 

OrderedDictionary , before:
key: 60   value:[(0, 60)]
key: 70   value:[(60, 70)]
key: 80   value:[(70, 80)]
key: 90   value:[(80, 90)]
key:100   value:[(90, 100)]

OrderedDictionary , after:
key: 60   value:[(0, 60), 56, 43, 52]
key: 70   value:[(60, 70), 68, 63, 60, 68, 63, 69]
key: 80   value:[(70, 80), 77, 76, 75, 78, 76, 72, 75, 75, 74, 77, 76, 76, 79, 74]
key: 90   value:[(80, 90), 82, 86, 89, 84, 89, 81, 82, 80, 84, 89, 88, 83, 83, 85, 86, 84, 86, 80, 81, 86]
key:100   value:[(90, 100), 94, 99, 100, 90, 95, 100, 96] 

(0, 60)        3
(60, 70)       6
(70, 80)       14
(80, 90)       20
(90, 100)      7

您可以使用bisect获取它所属的“范围”,并使用defaultdict作为每个范围中出现次数的计数器,例如:

from bisect import bisect
from collections import defaultdict
from itertools import chain, imap

raw_data="""
82   68   86   94   89   63   77   76   84    89
75   78   81   82   76   99   80   84   89    88
60   83   72   83   85   56   86   68   75   100
90   84   75   86   74   77   95   63   80    76
100   43  76   81   79   74   96   52   69    86""".lstrip()

# Make data into iterable of ints
data = chain.from_iterable(
    imap(int, line.split()) 
    for line in raw_data.splitlines()
)
# Counter
count = defaultdict(int)
for num in data:
    # Use 101 instead of 100 to cater for inclusion of 100
    count[bisect([0, 60, 70, 80, 90, 101], num)] += 1

结果count是:

^{pr2}$

正如苏姆建议的那样,你可以用熊猫来做这个。但是如果您想避免外部导入并且raw_data不是太大,可以使用:

import itertools
from collections import Counter

# 'kwargs' lets you implement more options
def cut ( data, breaks, **kwargs ):
    counts = Counter()
    ranges = itertools.izip(breaks, itertools.islice(breaks,1,None))
    for element in data:
        for range in ranges:
            if range[0] < element < range[1]:
                counts[range] += 1
                break
    return counts

# Call 'cut'
cut( raw_data, (0,60,70,80,90,100) )

Acknowledgements

相关问题 更多 >

    热门问题