Python 如何在不忽略数字的情况下“和”数据?

Python 如何在不忽略数字的情况下“和”数据?,python,numpy,Python,Numpy,假设我有一个数字18573628,其中每个数字代表某种标志,我想检查第四个标志的值是否设置为7 我不想使用索引。我想以某种方式使用旗帜遮罩,例如: 00070000 我通常会使用NPLogLogi和类似的东西,但会认为任何积极的值是正确的。在考虑一个数字的值时,我如何才能和?例如,使用 旗帜=18573628 及 掩码=00070000 将产生0.0001万美元 尽管尝试了不同的面具,例如 掩码=00040000 将产生00000000您所能做的是 if (x // 10**n % 10) ==

假设我有一个数字18573628,其中每个数字代表某种标志,我想检查第四个标志的值是否设置为7

我不想使用索引。我想以某种方式使用旗帜遮罩,例如:

00070000

我通常会使用NPLogLogi和类似的东西,但会认为任何积极的值是正确的。在考虑一个数字的值时,我如何才能和?例如,使用

旗帜=18573628

掩码=00070000

将产生0.0001万美元

尽管尝试了不同的面具,例如

掩码=00040000

将产生00000000

您所能做的是

if (x // 10**n % 10) == y:
    ...

要检查从右侧开始的x计数的第n位是否等于y,必须对十进制掩码使用除法和模运算:

flags = 18573628
mask = 10000

if (flags / mask) % 10 == 7:
    do_something
如果标志和掩码是十六进制值,则可以执行以下操作:

flags = int("18573628", 16)
mask = int("00070000", 16)
result = flags & mask

print(hex(result))
=> '0x70000'

您可以将输入的数字转换为一个数字数组,然后简单地用特定的索引将这些数字索引到该数组中。为了进行转换,我们可以使用np.fromstring,如下所示-

In [87]: nums = np.fromstring(str(18573628),dtype=np.uint8)-48

In [88]: nums
Out[88]: array([1, 8, 5, 7, 3, 6, 2, 8], dtype=uint8)

In [89]: nums[3] == 7
Out[89]: True
假设我有一个数字18573628,其中每个数字代表某种标志,我想检查第四个标志的值是否设置为7

首先,像&这样的按位操作是按位操作的,也就是说,它们以2位为基数进行操作。它们不会在任何其他基数的数字上自然运行,尽管基数本身是2的幂也可以

坚持按位操作 您需要知道每个标志可以接受多少值,以确定每个标志需要编码多少位

如果要允许每个标志的值为0到9,则需要4位。然而,在这个方案中,您的数字不会像一个普通的整数那样,在每个4位组中存储一个以10为基数的数字称为二进制编码的十进制数

它的行为与普通整数不同的原因是,标志值1,2,3将存储为1*16**2+2*16+3,而不是您通常期望的1*10**2+2*10+3。因此,您需要编写一些代码来支持这种使用。然而,从右边的零开始提取标志n计数就变得非常困难

def bcdFlagValue(bcd, flagnum):
  if flagnum == 0:
    return bcd & 0x0F;
  return 0x0F & (bcd >> ((flagnum-1) * 4))
如果每个标志实际需要不同的值范围,则需要选择正确的位数,并适当调整移位和掩码值

在这两种情况下,如果要将标记打印为显示的基数为10的数字,则需要一个helper函数

要使用正常的基数10 正如6502所示,您需要使用除法和模运算,因为基数为10的数字不能均匀地适应基数为2的位,所以简单的位运算不起作用

笔记
BCD方法以复杂性、工作量和速度为代价节省了空间——从后面的评论中可以看出,直接使用数字字符串可能更简单,除非您确实需要每位数节省4位。

无需处理您案例的细节——SDSS数据,这应该记录在产品规范中,让我们看看一些选项

首先,您需要知道它是按大端还是小端顺序读取的,它的第一位是向右还是向左。然后你需要知道每个旗子的大小。对于一系列是非参数,它可以是1位0或1。对于最多四个选项,它可以是两个位00、01、10、11等。也可能有些组合是为将来的扩展而保留的,目前没有意义,并且不应该出现在数据中。我也看到过标志大小变化的例子,所以前n位表示参数x,后n位表示参数y,等等

作为Landsat-8卫星图像的一部分,这一概念得到了很好的解释:


要读取这些值,您需要将基数为10的整数转换为二进制,并在指定的块中遍历它,再转换回int以根据产品规格获得参数值。

您通常会使用位作为掩码,而不是十进制digits@njzk2当然,但在我的上下文中,18573628中的每一位都可以是任意数字,不只是开或关。也许我需要某种3d位掩码,你需要能够隔离多个数字,或者一次只隔离一个数字?没有3d位掩码这样的东西。按位操作之所以有效,是因为它们是在位上执行的。如果您想使用十进制数字作为标志(没有人这么做),那么您必须使用自己的解决方案。你不能只发明你自己的系统,而期望现有的工具也能以同样的方式工作。@Two Bitalchest正如你所知,我之所以建立这个系统,是因为我需要分析斯隆数字巡天观测数据中给出的标志,这些数据和我描述的一模一样。例如,特定星系上的r波段星等标志为225074960195600。每个数字可以有不同的值,它们的含义都不同。所以我不是在设计我自己的系统,很明显
实际上,并不是没有人使用十进制标志,因为SDS是一个相当大的操作。我想对此进行表决,但不想破坏ID和rep值的并列。