【问题标题】:Vectorized conversion of decimal integer array to binary array in numpynumpy中十进制整数数组到二进制数组的向量化转换
【发布时间】:2018-12-30 10:50:03
【问题描述】:

我正在尝试将整数数组转换为它们在 python 中的二进制表示。我知道原生 python 有一个名为bin 的函数可以做到这一点。 Numpy 也有类似的功能:numpy.binary_repr

问题是这些都不是矢量化方法,因为它们一次只取一个值。因此,为了让我转换整个输入数组,我必须使用 for 循环并多次调用这些函数,这不是很有效。

有没有什么方法可以在没有 for 循环的情况下执行这种转换?这些函数是否有任何矢量化形式?我试过numpy.apply_along_axis 但没有运气。我也尝试过使用np.fromitermap,但也没有成功。

我知道类似的问题已经被问过几次(例如here),但给出的答案实际上都没有向量化。

将不胜感激指出我的任何方向!

谢谢 =)

【问题讨论】:

  • 只是出于好奇,您的数据有多大?只需对 1MM 项目运行简单的 [np.binary_repr(z) for z in x] 列表理解并使用 1.41 s ± 182 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
  • 我将使用的数据集可能不会那么大,通常在 1,000 左右,也许 10,000 左右。但我将不得不多次评估目标函数以进行优化,因此我试图在找到的每个角落都减少一些处理时间。
  • 你的整数有多少位,它们是有符号的还是无符号的?
  • 无符号整数 - 我只会使用正整数。我必须转换的最大 int 可能是 10,000。所以可能 16 位就可以了。

标签: python arrays numpy binary vectorization


【解决方案1】:

最简单的方法是使用binary_reprvectorize,它将保留原始数组形状,例如:

binary_repr_v = np.vectorize(np.binary_repr)
x = np.arange(-9, 21).reshape(3, 2, 5)
print(x)
print()
print(binary_repr_v(x, 8))

输出:

[[[-9 -8 -7 -6 -5]
  [-4 -3 -2 -1  0]]

 [[ 1  2  3  4  5]
  [ 6  7  8  9 10]]

 [[11 12 13 14 15]
  [16 17 18 19 20]]]

[[['11110111' '11111000' '11111001' '11111010' '11111011']
  ['11111100' '11111101' '11111110' '11111111' '00000000']]

 [['00000001' '00000010' '00000011' '00000100' '00000101']
  ['00000110' '00000111' '00001000' '00001001' '00001010']]

 [['00001011' '00001100' '00001101' '00001110' '00001111']
  ['00010000' '00010001' '00010010' '00010011' '00010100']]]

【讨论】:

    【解决方案2】:

    我发现(到目前为止)最快的方法是使用pd.Series.apply() 函数。

    以下是测试结果:

    import pandas as pd
    import numpy as np
    
    x = np.random.randint(1,10000000,1000000)
    
    # Fastest method
    %timeit pd.Series(x).apply(bin)
    # 135 ms ± 539 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
    
    # rafaelc's method
    %timeit [np.binary_repr(z) for z in x]
    # 725 ms ± 5.31 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    
    # aparpara's method
    binary_repr_v = np.vectorize(np.binary_repr)
    %timeit binary_repr_v(x, 8)
    # 7.46 s ± 24.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    

    【讨论】:

      猜你喜欢
      • 2017-01-31
      • 2021-10-13
      • 1970-01-01
      • 1970-01-01
      • 2021-01-17
      • 2016-07-10
      • 2021-05-18
      • 2021-08-10
      • 1970-01-01
      相关资源
      最近更新 更多