繁体   English   中英

Numpy根据阈值更改元素,然后逐元素相加

[英]Numpy change elements based on threshold and then do element by element addition

我有3247个197x10尺寸矩阵。 我需要对它们进行扫描,如果值大于1,则将其设置为1。如果值小于或等于1,我想将其设置为零。 然后,我必须将此修改后的矩阵添加到其他3246集的修改后的矩阵中。 这是我到目前为止的内容:

for i in range(LOWER, UPPER + 1):
    fname = file_name+str(i)+".txt"
    cur_resfile = np.genfromtxt(fname, delimiter = ",", skiprows = 1)
    m_cur = cur_resfile

    m_cur[m_cur <= 1] = 0
    m_cur[m_cur > 1 ] = 1

    m_ongoing = m_ongoing + m_cur

我希望m_ongoing保持正在进行的运行总和,以便可以将其保存到文件中。 但是,它不起作用,似乎只是在循环中写入最后一个m_cur。 如果我总共运行3次循环,则有些单元格相互之间都具有1s,因此我希望有几个3s。 我当然希望有很多2,但是我只会看到1和0。

做我想做的最好的方法是什么?

-根据条件更改值

-接受大量矩阵,然后逐个元素地添加所有元素,以为每个单元格创建运行总和。

您可以使用numpy.clip()

for i in range(LOWER, UPPER + 1):
    fname = file_name+str(i)+".txt"

    cur_resfile = np.genfromtxt(fname, delimiter = ",", skiprows = 1)

    m_ongoing += cur_resfile.clip(0,1)

编辑回答所问的问题:

m_ongoing = np.zeros((197,10))

for i in range(LOWER, UPPER + 1):
    fname = file_name+str(i)+".txt"
    cur_resfile = np.genfromtxt(fname, delimiter = ",", skiprows = 1)

    # add one to the places where cur_file > 1
    m_ongoing[cur_resfile > 1] += 1

正如@RootTwo所建议的那样,clip()是一个很好的内置numpy内置函数。 但是出于性能原因,您可以在数据的3D“堆栈”上使用矢量化操作。

例:

import numpy as np
#simulating your data as a list of 3247 2D matrices, each 197x10
some_data = [np.random.randint(-2,2,(197,10)) for _i in range(3247)]
#stack the matrices
X = np.dstack(some_data)
print(X.shape)

(197,10,3247)

Y = X.clip(0,1)
Z = Y.sum(axis=2)
#Z is now the output you want!
print(Z.shape)

(197,10)

编辑:添加计时结果,并更改我的答案

因此,我的建议似乎是创建一个深度堆栈并使用clip和sum函数的单个应用程序是不明智的。 我进行了一些时序测试,发现增量方法更快,主要是由于分配大3D数组的分配时间开销。

在这些测试中,我考虑了数据加载方面,因为两种方法都相同。 以下是将ipython中的两种方法与%timeit宏进行比较的结果。

import numpy as np
# some_data is simulated as in the above code sample
def f1(some_data):
    x = some_data[0]
    x = x.clip(0,1)
    for y in some_data[1:]:
        x += y.clip(0,1)
    return x

def f2(some_data):
    X = np.dstack(some_data)
    X = X.clip(0,1)
    X = X.sum(axis=2)
    return X

%timeit x1 = f1(some_data)

10个循环,最佳3:每个循环28.1毫秒

%timeit x2 = f2(some_data)

10个循环,最好3:每个循环103毫秒

因此,相对于在堆栈数据后进行单个操作而言,增量执行该过程的速度提高了3.7倍。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM