【问题标题】:create new numpy array base on exist numpy array after many caculate step经过多次计算步骤后,基于退出 numpy 数组创建新的 numpy 数组
【发布时间】:2022-01-09 12:26:25
【问题描述】:

我有一个像这样的二维数组 numpy :


s = np.array([[ 5.,  4., np.nan,  1., np.nan],
       [np.nan,  4.,  4.,  2.,  2.],
       [ 3., np.nan, np.nan,  5.,  5.],
       [np.nan,  3.,  4.,  4., np.nan]])

#now i want to create a new np array s1 base on s like this

s1= np.empty((len(s),len(s)))
for i  in range(len(s)):
    a = np.abs(s - s[i])
    a = np.nanmean(a, axis=1)
    w = 1 / (a + 0.001)
    s1[i] = w
s1
array([[1000.        ,    1.99600798,    0.33322226,    0.49975012],
       [   1.99600798, 1000.        ,    0.33322226,    0.999001  ],
       [   0.33322226,    0.33322226, 1000.        ,    0.999001  ],
       [   0.49975012,    0.999001  ,    0.999001  , 1000.        ]])

#without use for loop i write like this 

def f(x,y):
    a = np.abs(s[y]-s[x])
    a = np.nanmean(a)
    if np.isnan(a):
        return 0
    w = 1/(a+0.001) #not let 1/0
    return w

s1 = np.fromfunction(np.vectorize(f),(len(s),len(s)),dtype='int')
s1
array([[1000.        ,    1.99600798,    0.33322226,    0.49975012],
       [   1.99600798, 1000.        ,    0.33322226,    0.999001  ],
       [   0.33322226,    0.33322226, 1000.        ,    0.999001  ],
       [   0.49975012,    0.999001  ,    0.999001  , 1000.        ]])

首先我想问的是我的 np.fromfunction 对吗? 其次,有没有其他方法可以用numpy重写这段代码而不使用for循环?

【问题讨论】:

    标签: python arrays numpy


    【解决方案1】:

    怎么样

    >>> 1/(
            1e-3 + np.nanmean(
                np.abs(s - s[:, None,:]),
                axis=2
            )
        )
    array([[1.00000000e+03, 1.99600798e+00, 3.33222259e-01, 4.99750125e-01],
           [1.99600798e+00, 1.00000000e+03, 3.33222259e-01, 9.99000999e-01],
           [3.33222259e-01, 3.33222259e-01, 1.00000000e+03, 9.99000999e-01],
           [4.99750125e-01, 9.99000999e-01, 9.99000999e-01, 1.00000000e+03]])
    

    或者以完全 numpy 惯用的方式

    >>> np.reciprocal(1e-3 + np.nanmean(np.abs(s - s[:, np.newaxis, :]), axis=2))
    array([[1.00000000e+03, 1.99600798e+00, 3.33222259e-01, 4.99750125e-01],
           [1.99600798e+00, 1.00000000e+03, 3.33222259e-01, 9.99000999e-01],
           [3.33222259e-01, 3.33222259e-01, 1.00000000e+03, 9.99000999e-01],
           [4.99750125e-01, 9.99000999e-01, 9.99000999e-01, 1.00000000e+03]])
    

    其中,截至 2021 年 12 月,np.newaxisNone

    【讨论】:

    • 谢谢先生,您又为我节省了 1 时间。我在哪里可以阅读有关在 numpy 中创建新轴的文档,我在 nympy doc 中阅读了 np.newaxis,但它是如此基本,......我真的不知道它是如何工作的
    • 不客气@robocon20x 确实,你是对的:如果你掌握了类似 newaxis 的东西,你的 NumPy 生活会容易得多。掌握这件事的第一个(好的)链接是 How does numpy.newaxis work and when to use it?
    【解决方案2】:

    您可能正在寻找纯粹的 numpy 解决方案:

    repeat_s_by_array = np.repeat(s[np.newaxis,:,:], repeats=len(s), axis=0) 
    repeat_s_by_rows = np.repeat(s, repeats=len(s), axis=0).reshape(len(s),len(s),-1)
    abs_vals = np.abs(repeat_s_by_array - repeat_s_by_rows)
    mean = np.nanmean(abs_vals, axis=-1)
    s1 = 1 / (mean + 0.001)
    

    或者你可以做一个单行:

    s1 = 1 / (np.array([np.nanmean(np.abs(s - s[i]), axis=1) for i in range(len(s))]) + 0.001)
    

    【讨论】:

    • 如果我将 s 行分成许多部分,调用 a 是行数。我应该将重复从 len(s) 更改为 a 吗?您的代码似乎适用于小尺寸的 s
    • 如果您的工作与原始问题中的相同,则必须是repeats=len(a)。但是因为 numpy 解决方案处理的是更大的数组,所以如果 s 有很多行,那么您的原始循环构造或我的答案中的单行可能会开始表现更好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-19
    • 2017-12-30
    • 2022-01-07
    • 1970-01-01
    • 2023-03-12
    相关资源
    最近更新 更多