簡體   English   中英

為2D陣列實現numpy in1d?

[英]Implementation of numpy in1d for 2D arrays?

我有一個2D numpy數組S代表一個狀態空間,有80000000行(作為狀態)和5列(作為狀態變量)。

我用S初始化K0,並且在每次迭代中,我對Ki中的所有狀態應用狀態轉移函數f(x),並刪除其f(x)不在Ki中的狀態,從而得到Ki + 1。 直到它收斂,即Ki + 1 = Ki。

這樣做需要很長時間:

K = S
to_delete = [0]
While to_delete:
    to_delete = []
    for i in xrange(len(K)):
        if not f(i) in K:
        to_delete.append(K(i))
    K = delete(K,to_delete,0)

所以我想做一個矢量化的實現:

在列中切片K,應用f並再次連接它們,從而以某種方式獲得f(K)。

現在的問題是如何獲得一個長度為len(K)的數組,比如Sel,其中每一行Sel [i]確定f(K [i])是否在K中。正好像in1d函數一樣。

那么制作起來會很簡單

K=K[Sel]]

您的問題很難理解,因為它包含無關的信息並包含拼寫錯誤。 如果我理解正確,你只需要一種有效的方法對2D數組的行執行設置操作(在這種情況下是Kf(K)的行的交集)。

如果您創建結構化數組視圖,則可以使用numpy.in1d執行此操作。

碼:

如果這是K

In [50]: k
Out[50]:
array([[6, 6],
       [3, 7],
       [7, 5],
       [7, 3],
       [1, 3],
       [1, 5],
       [7, 6],
       [3, 8],
       [6, 1],
       [6, 0]])

這是f(K) (對於這個例子,我從第一個col中減去1並在第二個col中加1):

In [51]: k2
Out[51]:
array([[5, 7],
       [2, 8],
       [6, 6],
       [6, 4],
       [0, 4],
       [0, 6],
       [6, 7],
       [2, 9],
       [5, 2],
       [5, 1]])

然后你可以通過做這樣的事情找到在f(K)找到的K所有行:

In [55]: k[np.in1d(k.view(dtype='i,i').reshape(k.shape[0]),k2.view(dtype='i,i').
reshape(k2.shape[0]))]
Out[55]: array([[6, 6]])

viewreshape創建平面結構化視圖,以便每行顯示為in1d的單個元素。 in1d創建匹配項的k的布爾索引,用於表示索引k並返回已過濾的數組。

以上答案很棒。

但是,如果一個人不想與結構化數組混合並想要一個不關心數組類型的解決方案,也不想關注數組元素的維度 ,我想出了這個:

k[np.in1d(list(map(np.ndarray.dumps, k)), list(map(np.ndarray.dumps, k2)))]

基本上, list(map(np.ndarray.dumps, k))而不是k.view(dtype='f8,f8').reshape(k.shape[0])

考慮到這個解決方案慢了約50倍。

k = np.array([[6.5, 6.5],
       [3.5, 7.5],
       [7.5, 5.5],
       [7.5, 3.5],
       [1.5, 3.5],
       [1.5, 5.5],
       [7.5, 6.5],
       [3.5, 8.5],
       [6.5, 1.5],
       [6.5, 0.5]])
k = np.tile(k, (1000, 1))

k2 = np.c_[k[:, 0] - 1, k[:, 1] + 1]


In [132]: k.shape, k2.shape
Out[132]: ((10000, 2), (10000, 2))

In [133]: timeit k[np.in1d(k.view(dtype='f8,f8').reshape(k.shape[0]),k2.view(dtype='f8,f8').reshape(k2.shape[0]))]
10 loops, best of 3: 22.2 ms per loop

In [134]: timeit k[np.in1d(list(map(np.ndarray.dumps, k)), list(map(np.ndarray.dumps, k2)))]
1 loop, best of 3: 892 ms per loop

小輸入可能是邊際的,但對於操作,它需要1小時20分鍾而不是2分鍾。

不確定我是否完全理解你的問題,但是如果Paul的解釋是正確的,那么可以使用numpy_indexed包在一條可讀的行中有效地解決它並完全向量化:

import numpy_indexed as npi
K = npi.intersection(K, f(K))

此外,這適用於任何類型或形狀的行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM