2010-11-26 51 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