python histo 改变 bins 大小_关于python:如何从bins中分配整数值

我试图找到一种方法,根据变量所在的位置来指定一个数值。即:

variable = 23

if variable < -100:

return_value = -15

elif variable <= -5:

return_value = -4

elif variable <= 5:

return_value = 18

else:

return_value = 88

当然,我可以创建一个包含buckets/values的列表,并在找到正确的值时迭代并返回:

bucket_values = [(-100, -15), (-5, -4), (5, 18)]

default = 88

variable = 100

for lower_bound, value in bucket_values:

if variable < lower_bound:

return_value = value

break

else:

return_value = default

但是,我需要检查下限和上限以及相等性,即,如果它是循环的第一次迭代,我必须检查是否是下一个循环(

我在找这样的东西(红宝石):

buckets = [

[:

[:<=, 5, -10],

[:<=, 10, 3],

[:>, 60, 40]]

# Pass bucket to a method

我的问题是:是否有一种方法可以通过变量边界和值来实现这一点?

我不确定这个问题的好题目是什么。欢迎任何建议。

检查这个答案…我不知道这是不是你要找的

您首先想到的代码是什么?如果你能把这个添加到问题中,W可以帮助你把它转换成python。

@安沃维奇,我不想找其他的。因为这会迫使桶的数量增加。

@Ruby i中的TobiasWilfert也可以这样做:buckets=[:,60,40]],然后将其传递给一个方法。在python中有类似的东西吗?

如果在您的问题中编写精确的Ruby等价物,那么在python中找到类似的东西可能会更容易,您的数字是否只是整数,或者它们也可以是浮点数?

@在我的例子中,只取整数。我编辑了我的问题来添加红宝石桶。

这被称为binning,有许多现有的解决方案。你能用pandas库吗?它有pd.cut()库吗?大熊猫的分田改造

@据我所知,smci pd.cut()将分为容器,但我看不到下限和上限,即如果我创建容器[0、10、20],它将创建2个容器[0-10]和[10-20],但没有用于说[-inf-0]或[20-inf]。如果我错了,我会更进一步。但这正是我想要的答案!

@Jubonn:通常情况下是相邻的独立垃圾箱,因此垃圾箱的顶部(n-1)是垃圾箱的底部,但您需要不相交的垃圾箱。您也可以包括丢失的箱,然后将非法/丢失的箱值映射到您想要的任何内容。btw、np.ninf、np.pinf是合法的bin值。

@smci这是我要找的答案!因此pd和np.ninf/np.inf的组合。

您想要一个基本的python解决方案(使用operator.ge/gt/lt/le)还是一个pandas+numpy解决方案(使用pd.cut),或者不关心哪个?您希望您的输出是包含bin的底值,还是与bin的编号相对应的分类值,或者您不在乎哪个?

@SMCI将与代码库的其他部分进行验证。不想添加太多依赖项。我认为这两个都是我问题的正确答案。

使用模块operator非常简单。下面是一个例子:

>>> import operator

>>> bucket = (operator.ge, -100, operator.le, -5)

>>> def in_bucket(value, bucket): return bucket[0](value, bucket[1]) and bucket[2](value, bucket[3])

...

>>> in_bucket(-101, bucket)

False

>>> in_bucket(-100, bucket)

True

>>> in_bucket(-5, bucket)

True

>>> in_bucket(-4, bucket)

False

但是,通过定义更通用的结构,您可以做得更好:

>>> conditions = ((operator.ge, -100), (operator.le, -5))

>>> def match_conditions(value, conditions): return all(c[0](value, c[1]) for c in conditions)

...

>>> match_conditions(-101, conditions)

False

>>> match_conditions(-100, conditions)

True

>>> match_conditions(-5, conditions)

True

>>> match_conditions(-4, conditions)

False

当满足所有条件时,all运算符返回真值。bucket和conditions的关键区别在于,可以添加不涉及边界的条件,例如,值必须成对:

>>> conditions = ((operator.ge, -100), (operator.le, -5), (lambda v, _: v%2==0, None))

>>> match_conditions(-7, conditions)

False

>>> match_conditions(-6, conditions)

True

>>> match_conditions(-5, conditions)

False

现在,您可以使用字典来总结您的条件(您给出的第一个示例):

>>> value_by_conditions = {

... ((operator.lt, -100),): -15,

... ((operator.ge, -100), (operator.le, -5)): -4,

... ((operator.gt, -5), (operator.le, 5)): 18,

... ((operator.gt, 5),): 88,

... }

>>> next((v for cs, v in value_by_conditions.items() if match_conditions(23, cs)), None)

88

>>> next((v for cs, v in value_by_conditions.items() if match_conditions(-101, cs)), None)

-15

>>> next((v for cs, v in value_by_conditions.items() if match_conditions(-100, cs)), None)

-4

笔记:

我使用元组,因为列表不可哈希(因此不能用作dict键);

next((x for x in xs if ), None)取xs中通过测试的第一个元素。如果没有元素通过测试,则返回默认值None;

在旧版本的python(<3.7)中,您不能保证测试的顺序。如果你有重叠的条件,这很重要。

这显然是次优的,因为您测试的是value < 100,还是value >= 100等。

这真的是Python吗?我不太确定。请浏览https://www.python.org/dev/peps/pep-0020/了解您的想法。

如果我理解你的话,对于每一个"桶",你都有一个间隔。要检查值是否属于某个间隔,可以定义一个函数:

def check_value(value, interval):

if value in range(interval[0], interval[1]+1):

print('Value ', value)

print('Interval ', interval)

else:

pass

现在,只需迭代一系列间隔来查找值所属的位置:

for interval in list_of_intervals:

check_value(value, interval)

这相当于@smci提到的pd.cut()函数。它不包括上下限。

我觉得这是相当不错的Python,但我不推荐它

>>> variable = 23

>>> return_value = -5 if variable

>>> print(return_value)

88

注意,88是默认值。编辑

您可以创建一个基于与上面显示的if... else相同概念的函数。函数如下所示:

def pythonic(variable, bucket_values, default):

for k,v in bucket_values:

return_value = v if variable

if return_value !="---":

return return_value

return default

你可以这样使用它:

>>> variable = 23

>>> bucket_values = [(-100, -15), (-5, -4), (5, 18)]

>>> print(pythonic(variable, bucket_values, 88))

88

>>> variable = 1

>>> print(pythonic(variable, bucket_values, 88))

18

我正在寻找一种可变值和边界的方法。因此,如果其他人不适合我。

@朱邦,我编辑了我的答案,希望这对你有用:)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值