python - 根据多种条件将列表中的项目替换为其他项目(小列表)

标签 python python-3.x numpy foreach linspace

我有一个数字列表,我想根据几个条件用列表二进制模式替换每个数字。我有一个这样做的工作代码,但我想知道是否有更快更有效的代码,因为如果我想添加更多条件。

谢谢

import numpy as np
n = []
z = np.linspace(0,5,8)
t = [3.8856, 4.1820, 2.3040, 1.0197, 0.4295, 1.5178, 0.3853, 4.2848, 4.30911, 3.2299, 1.8528, 0.6553, 3.3305, 4.1504, 1.8787]
for i in t:
    if i>=z[0] and i<z[1]:
        n.extend([0,0,0,0,0])
    elif i>=z[1] and i<z[2]:
        n.extend([0,0,0,0,1])
    elif i>=z[2] and i<z[3]:
        n.extend([0,0,0,1,0])
    elif i>=z[3] and i<z[4]:
        n.extend([0,0,0,1,1])
    elif i>=z[4] and i<z[5]:
        n.extend([0,0,1,0,0])
    elif i>=z[5] and i<z[6]:
        n.extend([0,0,1,0,1])
    elif i>=z[6] and i<z[7]:
        n.extend([0,0,1,1,0])
new_n = np.asarray(n).reshape(len(t),5) # new_n is the final pattern I want.

最佳答案

这本身不是一个答案,但由于使用 numpy 而不是 python 的 for 循环,它可能会更快。

首先,您想要执行一些binning :

>> bins = np.digitize(t, z) - 1 # minus 1 just to align our shapes
array([5, 5, 3, 1, 0, 2, 0, 5, 6, 4, 2, 0, 4, 5, 2])

这会告诉您每个值都在哪个容器中。接下来,按顺序定义您的模式:

>> patterns = np.array([
    [0,0,0,0,0],
    [0,0,0,0,1],
    [0,0,0,1,0],
    [0,0,0,1,1],
    [0,0,1,0,0],
    [0,0,1,0,1],
    [0,0,1,1,0],
])

现在,对于一些 numpy 魔法,不要追加/扩展,而是创建一个充满零的数组(这几乎总是更快)。该数组的形状为(len(t), len(z)-1)。使用this SO answer ,我们也会进行one-hot编码:

>> inds = np.zeros((len(t), len(z)-1))
>> inds[np.arange(len(t)), bins] = 1
>> inds
array([[0., 0., 0., 0., 0., 1., 0.],
       [0., 0., 0., 0., 0., 1., 0.],
       [0., 0., 0., 1., 0., 0., 0.],
       .....,
       [0., 0., 0., 0., 0., 1., 0.],
       [0., 0., 1., 0., 0., 0., 0.]])

最后,我们需要的是矩阵乘法

>> inds @ patterns
array([[0., 0., 1., 0., 1.],
       [0., 0., 1., 0., 1.],
       [0., 0., 0., 1., 1.],
       ....
       [0., 0., 1., 0., 1.],
       [0., 0., 0., 1., 0.]])

我没有进行质量计时测试,但根据我的小实验,以下是我的结果:

您的循环:每个循环 17.7 µs ± 160 ns(7 次运行的平均值 ± 标准差,每次 100000 次循环) 我的实现:每个循环 8.49 µs ± 125 ns(7 次运行的平均值 ± 标准差,每次 100000 个循环)

这可能会或可能不会很好地扩展到更大的数据集。希望这有帮助:)


编辑:关注Alexander Lopatin's回答 我很感兴趣地看到我的方法明显慢了。经过进一步调查,我得出的结论之一是 numpy 的函数有一些显着的开销,对于很少的 t 值而言,这并不是一个便宜的代价。对于较大的列表,numpy 开销微不足道,但性能增益却不容忽视:

enter image description here

timings = {
    10: [7.79, 24.1, 21.7],
    16: [10.7, 29.9, 22.9],
    24: [14.6, 40.5, 23.4],
    33: [19.1, 48.6, 23.4],
    38: [21.9, 55.9, 23.9],
    47: [26.7, 66.2, 24.1],
    61: [33, 79.5, 24.7],
    75: [40.8, 92.6, 25.8],
    89: [47.6, 108, 26.2],
    118: [60.1, 136, 27.4],
    236: [118, 264, 33.1],
    472: [236, 495, 40.9],
    1000: [657, 922, 52],
    10000: [6530, 9090, 329]
}

缩放:

enter image description here

关于python - 根据多种条件将列表中的项目替换为其他项目(小列表),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55112218/

相关文章:

python - 类没有属性X

使用 NTLM 进行 Python Mechanize 时出现 AttributeError : HTTPResponse instance has no attribute '__iter__'

(任何)类的 Python 类型提示

python - opencv 2.4.8未导入

python - 如何从系数列表构建多项式 lambda 函数?

python - python3.5中使用split函数

python - 以表格式使用 hdf 时内存泄漏?

python - 使用 `contains` 合并 DataFrame(不是完全匹配!)

python - Zip 文件破解器 python 3 将仅在文本文件末尾使用密码

java - 将 numpy 数组转换为 Android/Java 可读格式?