【问题标题】:using numpy arrays for integer and array inputs将 numpy 数组用于整数和数组输入
【发布时间】:2025-11-23 21:55:01
【问题描述】:

我是 Matlab 用户,正在尝试使用 Python。我尝试在 Python 中编写一个 de2bi 函数的最小示例(它将十进制转换为二进制为 right-msb),这是我之前在 Matlab 中使用的。但是,我对 numpy 数组感到困惑。

Python 代码:

import numpy as np

def de2bi(d, n)
    d = np.array(d)
    power = 2**np.arange(n)
    d = d * np.ones((1,n))
    b = np.floor((d%(2*power))/power)
    return b

Python 输出:

>>> print(de2bi(13,8))
[[ 1.  0.  1.  1.  0.  0.  0.  0.]]

print(de2bi([13,15],8)) #This line fails

Matlab 代码:

function b = d2b( d, n )
    d = d(:);
    power = ones(length(d), 1)*(2.^(0 : n-1));
    d = d * ones(1, n);
    b = floor(rem(d, 2*power)./power);
end

Matlab 输出:

>> d2b(13,8)

ans =

     1     0     1     1     0     0     0     0

>> d2b([13,15],8)

ans =

     1     0     1     1     0     0     0     0
     1     1     1     1     0     0     0     0

Matlab 代码适用于整数输入和整数数组。但是 python 代码适用于整数输入,但对于数组总是失败。如何在 Python 中自动管理整数和整数数组的操作?对不起,这可能是一个非常简单的问题,但我是 python 的新手。

提前致谢。

【问题讨论】:

  • flipud 的使用看起来很有趣。您应该能够像 matlab 一样编写 numpy 电源线,利用广播来生成二维数组。
  • @hpaulj 问题是当我尝试使用整数输入 x python 不会将其转换为 [x] 之类的列表,并且数组会更改为 [[x,y] 之类的列表列表] 为 [x,y] 当我手动转换它时。我想我需要得到 x 的 [x] 和 [x,y] 的 [[x],[y]],但我不知道如何像在 matlab 中那样用几行代码来管理这个简单的步骤。跨度>

标签: python arrays matlab numpy


【解决方案1】:

您的问题在于乘法:d = d * np.ones((1,n))。 NumPy 尝试执行逐元素乘法,但由于维度不匹配(您的数组只有一行)而失败。但是,当 d 是标量时,NumPy 可以推断出您的意思是乘以标量,因此代码会运行。

你真正想做的(据我所知)是将每个元素扩展为一个 n 长的行。一个可能的解决方案是创建一个中间数组来保存新值,因为数组的大小是不可更改的:

def d2b(d, n):
    d = np.array(d)
    d = np.reshape(d, (1, -1))
    power = np.flipud(2**np.arange(n))

    g = np.zeros((np.shape(d)[1], n))

    for i, num in enumerate(d[0]):
        g[i] = num * np.ones((1,n))
    b = np.floor((g%(2*power))/power)
    return b

【讨论】:

  • 我们真的需要循环吗? numpy 没有任何循环可以直接处理这个问题吗?
  • 我对此不是 100% 肯定,因为我们仍然依赖于标量数组乘法。也许您可以将操作转换为数组数组乘法 (np.dot()) ?也许用单位矩阵而不是单位矩阵,但我不确定那个的数学。
  • 感谢您的回答。我想有一种直接的方法可以获得相同的操作,而无需像我们在 matlab 中那样进入循环。我刚刚开始学习python,并尝试处理基础知识。我希望我们也会看到其他关于捷径的答案。 (很抱歉我还没有足够的声望,无法给你+1)
【解决方案2】:

这有帮助吗?

In [439]: d=np.array([13,15])
In [440]: power=np.ones((d.shape[0],1))*(2**np.arange(8))
In [441]: power
Out[441]: 
array([[   1.,    2.,    4.,    8.,   16.,   32.,   64.,  128.],
       [   1.,    2.,    4.,    8.,   16.,   32.,   64.,  128.]])
In [442]: np.floor((d[:,None]%(2*power))/power)
Out[442]: 
array([[ 1.,  0.,  1.,  1.,  0.,  0.,  0.,  0.],
       [ 1.,  1.,  1.,  1.,  0.,  0.,  0.,  0.]])

我们甚至不需要ones

In [443]: power = 2**np.arange(8)
In [444]: np.floor((d[:,None]%(2*power))/power)
Out[444]: 
array([[ 1.,  0.,  1.,  1.,  0.,  0.,  0.,  0.],
       [ 1.,  1.,  1.,  1.,  0.,  0.,  0.,  0.]])

当广播dpower 时,power 的维度扩展是自动的:d[:,None]%(2*power[None,:])。 MATLAB 中的ones 完成相同的维度扩展(到 (2,8) 形状的数组)。

可能希望以 d=np.atleast_1d(d) 开头,因此它将标量情况视为 1 元素数组。我们可以改进一些东西,使它在给定标量时返回一维数组,在给定列表或一维数组时返回二维。在 MATLAB 中,一切都是 2d 或更高的。


更好的是,在扩展 d 时使用 ellipsis。那么d可以是0d,1d,甚至是nd。

np.floor((d[...,None]%(2*power))/power)

【讨论】:

  • 感谢您的回答。它适用于d = [13,15],但即使在使用d=np.atleast_1d(d) 后,直接将d 分配给一个整数作为d = 13 也会给出IndexError。在 MATLAB 中它会自动将整数 x 转换为数组 [x],因此在操作过程中不会出现问题。
  • 我发表了评论,但没有看到您对 np.floor((d[...,None]%(2*power))/power 的编辑。它现在也适用于 0d 数组。但是输出格式不同。这适用于正向操作,但不适用于逆向操作。我可以通过编辑将我的解决方案也添加到您的答案中,然后接受您的答案吗?
  • atleast_1d 应该与标量一起使用。请记住,MATLAB 没有标量。一切都是二维的。您的 1 行 MATLAB 案例的形状为 (1,8),在 numpy 中它可能是 (8,)。