2010-11-26 49 views
10

我很努力地找到一個特定的Matlab編碼「模式」使用ismember的Numpy等價物。numpy(Python)中的matlab'ismember'的等價物?

不幸的代碼往往是大部分時間都在我的MATLAB腳本都花在所以我想找到一個有效的NumPy的等價物。

基本圖案由一個子集映射到一個更大的網格。我有一組鍵值對存儲爲並行數組,我想將這些值插入到以相同方式存儲的更大的鍵值對列表中。

爲了具體說,我有我映射到每月一次網格如下季度GDP數據。

quarters = [200712 200803 200806 200809 200812 200903]; 
gdp_q = [10.1 10.5 11.1 11.8 10.9 10.3]; 
months = 200801 : 200812; 
gdp_m = NaN(size(months)); 
[tf, loc] = ismember(quarters, months); 
gdp_m(loc(tf)) = gdp_q(tf); 

請注意,並非所有的宿舍出現在這樣兩個TFLOC要求變量個月的名單。

我看到的StackOverflow的類似的問題,但他們只給出一個純Python的解決方案(here),或者numpy的使用則不會返回祿參數(here)。

在我的特殊應用領域,這個特殊的代碼模式往往再出現一遍又一遍,並使用了大部分的在我的職務CPU時間,所以這裏的高效解決方案是對我來說真的很重要。

評論或重新設計的建議也受歡迎。

+0

如果之後你會實現它自己:1.對象採取散,你已經有一個數字 - 對它們進行排序,並使用二進制搜索。 2.另一種方法 - 使用散列表 – Mikhail 2010-11-26 18:02:39

+0

我認爲這[由Alex Martelli回答](http://stackoverflow.com/questions/1273041/how-can-i-implement-matlabs-ismember-command-in-python/1273815# 1273815)是最好的,你可以得到。 – 2010-11-27 11:11:05

回答

6

如果幾個月進行排序,使用np.searchsorted。否則,排序,然後用np.searchsorted

import numpy as np 
quarters = np.array([200712, 200803, 200806, 200809, 200812, 200903]) 
months = np.arange(200801, 200813) 
loc = np.searchsorted(months, quarters) 

np.searchsorted返回插入位置。如果您的數據甚至不是在正確的範圍內的可能性,你可能希望有一個檢查算賬:

valid = (quarters <= months.max()) & (quarters >= months.min()) 
loc = loc[valid] 

這是一個O(N日誌N)解決方案。如果你的程序在運行時間上仍然是一個大問題,那麼你可以使用哈希方案在C(++)中執行一個子程序,這將是O(N)(以及避免一些常數因素,當然)。

2

我想你可以重新設計你給那麼它不使用ISMEMBER功能的MATLAB原代碼示例。這可能會加快MATLAB代碼,並使其更容易在Python重新實現,如果你仍然想:

quarters = [200712 200803 200806 200809 200812 200903]; 
gdp_q = [10.1 10.5 11.1 11.8 10.9 10.3]; 

monthStart = 200801;    %# Starting month value 
monthEnd = 200812;    %# Ending month value 
nMonths = monthEnd-monthStart+1; %# Number of months 
gdp_m = NaN(1,nMonths);   %# Initialize gdp_m 

quarters = quarters-monthStart+1; %# Shift quarter values so they can be 
            %# used as indices into gdp_m 
index = (quarters >= 1) & (quarters <= nMonths); %# Logical index of quarters 
                %# within month range 
gdp_m(quarters(index)) = gdp_q(index); %# Move values from gdp_q to gdp_m 
+0

+1:ismember做各種額外的東西,比如調用你的情況下不需要的`unique`,你可以絕對簡化Matlab(或numpy)代碼。 – Jonas 2010-11-26 18:22:26