在Python中,什么是一种清晰、有效的方法来计算区域中的事物?

2024-10-01 00:21:52 发布

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

我在一个叫做事件的对象上循环。每个事件中都有一个特定的对象。我在计算具有特定特征的物体的比例。将这种方法想象成如下所示:

for event in events:
    countCars =+ 1
    if event.car.isBlue() is True:
        countCarsBlue =+ 1

print("fraction of cars that are blue: {fraction}".format(
    fraction = countCarsBlue / countCars))

现在,假设我想计算在另一个物体的特征区域中具有特定特征的物体的比例。所以,在我的例子中,我计算的是蓝色汽车的比例。现在,我想计算在汽车长度从0米到1米范围内蓝色汽车的比例,在汽车长度从1米到2米,从2米到3米,从3米到4米范围内蓝色汽车的比例,依此类推。你知道吗

考虑到我要处理大量的统计数据和比我的简单示例中的4个存储箱多得多的存储箱,假设存储箱宽度不变,那么构造这种类型计算的代码的好方法是什么?你知道吗

(对于可变料仓宽度,是否有合理的方法来实现这一点?)你知道吗


Tags: 对象方法eventfor宽度事件特征汽车
2条回答

如果您使用的是python3.4+,枚举实际上对此非常有用。下面是几个你可以做的例子:

import random
from enum import Enum
from collections import namedtuple


class Color(Enum):
    blue = 'blue'
    red = 'red'
    green = 'green'

Car = namedtuple('Car', ('color', 'length'))

cars = [Car(Color.blue, 10),
        Car(Color.blue, 3),
        Car(Color.blue, 9),
        Car(Color.red, 9),
        Car(Color.red, 7),
        Car(Color.red, 8),
        Car(Color.green, 3),
        Car(Color.green, 7),
        Car(Color.green, 2),
        Car(Color.green, 8),
        ]

print('# of blue cars:', sum(1 for car in cars if car.color == Color.blue))
print('# of cars with length between 3 and 7:',
      sum(1 for car in cars if 3 <= car.length <= 7))

random_color = random.choice(tuple(Color))
lower_limit = random.randint(1,10)
upper_limit = random.randint(lower_limit,10)
print('# of {} cars with length {} to {} (inclusive):'.format(random_color.name,
                                                              lower_limit,
                                                              upper_limit),
      sum(1 for car in cars if car.color == random_color
                            and lower_limit <= car.length <= upper_limit))

important_colors = (Color.blue, Color.green)
important_lengths = (1,2,3,5,7)

print('Number of cars that match some contrived criteria:',
      sum(1 for car in cars if car.color in important_colors
                            and car.length in important_lengths))

如果你说的是连续范围,lower < value < upper是一个很好的检查方法。若您有离散值(如颜色),您可以创建一个有趣的颜色集合,并检查该集合中的成员资格。还要注意的是,您可以很容易地使用可变的箱子大小。你知道吗

如果您对简单的计数感兴趣,还可以使用^{}。请注意,如果您的项目是引用对象,则更改一个集合中的某个项目将更改另一个集合中的某个项目:

In [15]: class Simple:
   ....:     def __init__(self, name):
   ....:         self.name = name
   ....:     def __repr__(self):
   ....:         return 'Simple(name={!r})'.format(self.name)
   ....:

In [16]: values = [Simple('one'), Simple('two'), Simple('three')]

In [17]: one = (values[0], values[-1])

In [18]: two = tuple(values[:2])

In [19]: one
Out[19]: (Simple(name='one'), Simple(name='three'))

In [20]: two
Out[20]: (Simple(name='one'), Simple(name='two'))

In [21]: one[0].name = '**changed**'

In [22]: one
Out[22]: (Simple(name='**changed**'), Simple(name='three'))

In [23]: two
Out[23]: (Simple(name='**changed**'), Simple(name='two'))

首先,编写一些代码来重新创建示例:

import random

class Event(object):
    def __init__(self):
        self.car = None

class Car(object):
    def __init__(self, isBlue, length):
        self._isBlue = isBlue
        self._length = length

    def isBlue(self):
        return self._isBlue

    def length(self):
        return self._length

    def __str__(self):
        return '{} car of {} m long.'.format('blue' if self.isBlue() else 'non-blue ', self.length())

好的,现在我随机创建十个car对象并将它们添加到event

totalNumberOfCars = 10
events = []
for _ in range(totalNumberOfCars):
    car = Car(random.choice([True, False]), random.randrange(5, 40)/10.)
    print car
    event = Event()
    event.car = car
    events.append(event)

对我来说,输出如下(您的输出当然可以不同):

blue car of 0.5 m long.
non-blue  car of 2.3 m long.
non-blue  car of 3.8 m long.
blue car of 2.1 m long.
non-blue  car of 0.6 m long.
blue car of 0.8 m long.
blue car of 0.5 m long.
blue car of 2.3 m long.
blue car of 3.3 m long.
blue car of 2.1 m long.

现在,如果我们想按地区统计我们的事件,您可以按以下步骤进行:

allBlueCars = sum(1 for event in events if event.car.isBlue())
print "Number of blue cars: {}".format(allBlueCars)

maxCarLen = 4
for region in zip(range(maxCarLen ), range(1, maxCarLen +1)):
    minlen, maxlen = region
    print "Cars between {} and {} m that are blue:".format(minlen, maxlen)
    blueCarsInRegion = [str(event.car) for event in events if event.car.isBlue() and minlen <= event.car.length() < maxlen]
    if blueCarsInRegion:
        print '\n'.join(['\t{}'.format(car) for car in blueCarsInRegion])
    else:
        print 'no blue cars in this region'
    fraction = float(len(blueCarsInRegion)) / allBlueCars
    print "fraction of cars that are blue and between {} and {} m long: {}".format(minlen, maxlen, fraction)
    print

对于上述示例数据,将打印:

Number of blue cars: 7
Cars between 0 and 1 m that are blue:
    blue car of 0.5 m long.
    blue car of 0.8 m long.
    blue car of 0.5 m long.
fraction of cars that are blue and between 0 and 1 m long: 0.428571428571

Cars between 1 and 2 m that are blue:
no blue cars in this region
fraction of cars that are blue and between 1 and 2 m long: 0.0

Cars between 2 and 3 m that are blue:
    blue car of 2.1 m long.
    blue car of 2.3 m long.
    blue car of 2.1 m long.
fraction of cars that are blue and between 2 and 3 m long: 0.428571428571

Cars between 3 and 4 m that are blue:
    blue car of 3.3 m long.
fraction of cars that are blue and between 3 and 4 m long: 0.142857142857

相关问题 更多 >