【问题标题】:what is the equivalent of Matlab's typecast function in R / Python / Julia什么是 R / Python / Julia 中 Matlab 的 typecast 函数的等价物
【发布时间】:2014-01-22 18:06:52
【问题描述】:

什么是 R 中 Matlab 的 typecast 函数的等价物?在 Python 中?在朱莉娅? Matlab的typecast函数的说明在这里:typecast

示例,在 Matlab 中

X = uint32([1 255 256])
X =
           1         255         256

Y = typecast(X, 'uint8') # little endian
Y =
   1   0   0   0  255   0   0   0   0   1   0   0

谢谢

请注意:我不是在寻找与 Matlab 的 cast 函数等效的 R / Python / Julia 函数(例如,我不是在 R 中寻找 as.integeras.character

编辑:

感谢 Julia / R / Python 的回答。 StackOverflow 允许我选择一个答案,但我对所有答案都投了赞成票。

【问题讨论】:

  • R 中没有。我也很困惑你什么时候想使用typecast。你想用你的数据做什么?我能想到的最接近的是format,但这只会以不同的方式打印您的数据。
  • @ScottRitchie:可能想澄清一下你的意思是什么语言没有,因为问题涉及多种语言。
  • 在 Python 中没有办法做到这一点,因为 Python 类型从位数等细节中抽象出来。你也许可以用 numpy.finagle 解决一些问题。没有任何解释你为什么要这样做,我和 Scott Ritchie 一样困惑于该操作的意义。
  • 我已经澄清了我对语言的评论。
  • 您可能会创建自己的typecast 函数,它只是将同一对象的多个表示形式存储在一个类结构中。

标签: python r matlab julia


【解决方案1】:

在 R 中,您可以将对象写入原始二进制连接并返回字节向量。这将使您获得与您的 uint8 输出示例等效的内容:

> X=c(1,255,256)
> mode(X)
[1] "numeric"

这里重要的是存储模式,而不是模式。所以我们将它设置为整数——相当于 uint32,即每个整数 4 个字节:

> storage.mode(X)
[1] "double"
> storage.mode(X)="integer"

现在我们可以使用writeBin。第二个参数是一个任意的原始向量,因此我们创建一个长度为零的临时向量。我们只关心返回值:

> Xraw = writeBin(X,raw(0))
> Xraw
 [1] 01 00 00 00 ff 00 00 00 00 01 00 00

使用readBin 进行反向操作:

> readBin(Xraw,"int",n=3)
[1]   1 255 256

将前 8 个字节解压成双精度:

> Xdoub = readBin(Xraw,"double",n=1)
> Xdoub
[1] 5.411089e-312

显然是一个无意义的值。但是让我们检查一下它的前 8 个字节是否相同:

> writeBin(Xdoub,raw(0))
[1] 01 00 00 00 ff 00 00 00

R 并不真正具有所有 C 级别的类型,因此如果您需要任何东西,您可以从原始字节构建它或编写一些 C 代码以与 R 函数链接。

【讨论】:

    【解决方案2】:

    在 Julia 中,您正在寻找 reinterpret

    julia> X = Uint32[1,255,256]
    3-element Array{Uint32,1}:
     0x00000001
     0x000000ff
     0x00000100
    
    julia> Y = reinterpret(Uint8,X)
    12-element Array{Uint8,1}:
     0x01
     0x00
     0x00
     0x00
     0xff
     0x00
     0x00
     0x00
     0x00
     0x01
     0x00
     0x00
    

    但是请注意,对于矩阵,即使第一个维度是单例,您也需要指定结果维度(因为您需要 4x3 还是 1x12 数组并不明确):

    julia> X = Uint32[1 255 256]
    1x3 Array{Uint32,2}:
     0x00000001  0x000000ff  0x00000100
    
    julia> Y = reinterpret(Uint8,X) # This won't work
    ERROR: result shape not specified
    
    julia> Y = reinterpret(Uint8,X,(1,12))
    1x12 Array{Uint8,2}:
     0x01  0x00  0x00  0x00  0xff  0x00  0x00  0x00  0x00  0x01  0x00  0x00
    

    【讨论】:

    • 有没有办法用多维数组做到这一点? Uint32[1,255,256] 但与 Uint32[[1 1], [1, 1]] ?
    【解决方案3】:

    Python/Numpy:

    >>> import numpy as np
    >>> x = np.array([1,255,256], dtype=np.int32)
    >>> y = x.view(np.uint8)
    

    (您可以类似地更改x 本身的类型:x.dtype = np.uint8)。

    输出:

    >>> x
    array([  1, 255, 256])
    >>> y
    array([  1,   0,   0,   0, 255,   0,   0,   0,   0,   1,   0,   0], dtype=uint8)
    

    请注意,y 是对x就地重新解释的view,因此y 中的任何更改都将反映在x 中:

    >>> y[:] = 255
    >>> x
    array([-1, -1, -1])
    

    MATLAB

    这是等效的 MATLAB 输出:

    >> x = int32([1,2,3])
    x =
               1           2           3
    >> y = typecast(x, 'uint8')
    y =
        1    0    0    0    2    0    0    0    3    0    0    0
    
    >> y(:) = 255
    y =
      255  255  255  255  255  255  255  255  255  255  255  255
    >> xx = typecast(y, 'int32')
    xx =
              -1          -1          -1
    

    如果您想在 MATLAB 中进行类型转换而不创建深层副本,请参阅typecastx MEX-function(它使用未记录的功能来创建共享数据副本)。


    注意 MATLAB 使用 saturation arithmetic,取消链接具有 modular arithmetic 的 Python:

    Python/Numpy

    # wraps around the other end
    >>> np.array(257, dtype=np.uint8)
    array(1, dtype=uint8)
    

    MATLAB

    % saturates at the maximum
    >> uint8(257)
    ans =
      255
    

    【讨论】:

      猜你喜欢
      • 2017-10-26
      • 2011-01-07
      • 2021-02-14
      • 1970-01-01
      • 2021-02-17
      • 1970-01-01
      • 2011-08-16
      • 2022-10-15
      • 2023-01-17
      相关资源
      最近更新 更多