我正在努力使用ismember找到特定Matlab编码“模式”的Numpy等价物。
不幸的是,这段代码往往是我的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);
请注意,并非所有季度都出现在月份列表中,因此 tf 和 loc 变量都是必需的。
我在StackOverflow上看到了类似的问题,但是他们要么只提供纯Python解决方案(here),要么使用numpy,然后不返回 loc 参数({{3 }})。
在我的特定应用领域,这种特殊的代码模式往往会反复出现并占用我函数的大部分CPU时间,因此这里的有效解决方案对我来说非常重要。
也欢迎提出意见或重新设计建议。
答案 0 :(得分: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 log N)解决方案。如果你的程序在运行时间方面仍然是一个大问题,你可能只是使用散列方案在C(++)中做这个子程序,这将是O(N)(以及避免一些常数因素,当然)。
答案 1 :(得分:2)
我认为您可以重新设计您提供的原始MATLAB代码示例,以便它不使用ISMEMBER函数。这可能会加速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
答案 2 :(得分:0)
尝试使用pypi的self.navigationController?.navigationBar.prefersLargeTitles = true
库。
ismember
示例:
pip install ismember