能够获得一个函数句柄并在批处理模式下使用它(即运行输入参数的不同组合)我想编写一个获取结构的函数(未知的字段名称),然后创建一个结构数组如下例所示:
P是输入,BP是我们期望的输出
function BP = createBP(P)
% P.A = 1:4;
% P.B = {'a','b','c'};
% So the output BP will be 4*3 = 12 different combination arranged this way:
% BP(1).A = 1
% BP(1).B = 'a'
% BP(2).A = 1
% BP(2).B = 'b'
% BP(3).A = 1
% BP(3).B = 'c'
% ....
% BP(12).A = 4
% BP(12).B = 'c'
这适用于任意P(具有任意数字和字段名称的结构)。
我对Matlab或Python解决方案感兴趣。这个例子是用Matlab编写的。
答案 0 :(得分:1)
您正在寻找两个列表中的笛卡尔积。要使用python计算它,您可以使用itertools.product:
a = range(4)
b = ['a', 'b', 'c']
p = itertools.product(a,b)
then p contains:
[(0, 'a'),
(0, 'b'),
(0, 'c'),
(1, 'a'),
(1, 'b'),
(1, 'c'),
(2, 'a'),
(2, 'b'),
(2, 'c'),
(3, 'a'),
(3, 'b'),
(3, 'c')]
答案 1 :(得分:0)
感谢@Johannes提及笛卡儿产品,这是Matlab解决方案:
function BP = createBP(P)
%CREATEBATCHOBJECT - get the structure and create batch BP structure Array
% Example of P:
% P.A = 1:4;
% P.B = {'a','b','c'};
% So the output BatchParam (BP) will be like this:
% 4*3 = 12 different combination so
% BP(1).A = 1
% BP(1).B = 'a'
% BP(2).a = 1
% BP(2).B = 'b'
% BP(3).A = 1
% BP(3).B = 'c'
% ....
% BP(12).A = 4
% BP(12).B = 'c'
% the output parameter BP (BatchParam) will be used by runBatch function to run given
% function on the BatchParam.
%
% This function uses allcomb which calculate the cartesiean product of elements. It
% make sure the input of allcomb be proper cell input and also create desired BP
% structure array from the product.
%% Parse P to proper cell for allcomb
fieldNames = fieldnames(P);
C = cell(numel(fieldNames),1); % C contains all field of P in a cell
for i = 1:numel(fieldNames)
C{i} = createCellFromData(P.(fieldNames{i}));
end
cartProduct = allcomb(C{:});
%% Convert Cartesian Product of the list to Arrays of Structure, BP:
% initialize the structure array (not necessary) // pre-allocate:
for i = 1:numel(fieldNames)
BP.(fieldNames{i}) = [];
end
BP = repmat(BP,1,size(cartProduct,1));
for i = 1:size(cartProduct,1) % for each product aka combination
for ii = 1:numel(fieldNames) % for each field
BP(i).(fieldNames{ii}) = cartProduct{i,ii};
end
end
end
%% Local Functions:
function C = createCellFromData(L)
% this function gets a input, L, which is a list, vector, character, etc and put each
% entry in a cell of a Cell: C.
switch class(L)
case 'double'
C = cell(1,numel(L));
for i = 1:numel(L)
C{i} = L(i);
end
case 'char'
C{1} = L;
case 'cell'
C = L;
otherwise
error('This class has not been implemented yet');
end
end
function A = allcomb(varargin)
% ALLCOMB - All combinations
% B = ALLCOMB(A1,A2,A3,...,AN) returns all combinations of the elements
% in the arrays A1, A2, ..., and AN. B is P-by-N matrix is which P is the product
% of the number of elements of the N inputs. This functionality is also
% known as the Cartesian Product. The arguments can be numerical and/or
% characters, or they can be cell arrays.
%
% Examples:
% allcomb([1 3 5],[-3 8],[0 1]) % numerical input:
% % -> [ 1 -3 0
% % 1 -3 1
% % 1 8 0
% % ...
% % 5 -3 1
% % 5 8 1 ] ; % a 12-by-3 array
%
% allcomb('abc','XY') % character arrays
% % -> [ aX ; aY ; bX ; bY ; cX ; cY] % a 6-by-2 character array
%
% allcomb('xy',[65 66]) % a combination
% % -> ['xA' ; 'xB' ; 'yA' ; 'yB'] % a 4-by-2 character array
%
% allcomb({'hello','Bye'},{'Joe', 10:12},{99999 []}) % all cell arrays
% % -> { 'hello' 'Joe' [99999]
% % 'hello' 'Joe' []
% % 'hello' [1x3 double] [99999]
% % 'hello' [1x3 double] []
% % 'Bye' 'Joe' [99999]
% % 'Bye' 'Joe' []
% % 'Bye' [1x3 double] [99999]
% % 'Bye' [1x3 double] [] } ; % a 8-by-3 cell array
%
% ALLCOMB(..., 'matlab') causes the first column to change fastest which
% is consistent with matlab indexing. Example:
% allcomb(1:2,3:4,5:6,'matlab')
% % -> [ 1 3 5 ; 1 4 5 ; 1 3 6 ; ... ; 2 4 6 ]
%
% If one of the arguments is empty, ALLCOMB returns a 0-by-N empty array.
%
% See also NCHOOSEK, PERMS, NDGRID
% and NCHOOSE, COMBN, KTHCOMBN (Matlab Central FEX)
% Tested in Matlab R2015a
% version 4.1 (feb 2016)
% (c) Jos van der Geest
% email: samelinoa@gmail.com
% History
% 1.1 (feb 2006), removed minor bug when entering empty cell arrays;
% added option to let the first input run fastest (suggestion by JD)
% 1.2 (jan 2010), using ii as an index on the left-hand for the multiple
% output by NDGRID. Thanks to Jan Simon, for showing this little trick
% 2.0 (dec 2010). Bruno Luong convinced me that an empty input should
% return an empty output.
% 2.1 (feb 2011). A cell as input argument caused the check on the last
% argument (specifying the order) to crash.
% 2.2 (jan 2012). removed a superfluous line of code (ischar(..))
% 3.0 (may 2012) removed check for doubles so character arrays are accepted
% 4.0 (feb 2014) added support for cell arrays
% 4.1 (feb 2016) fixed error for cell array input with last argument being
% 'matlab'. Thanks to Richard for pointing this out.
narginchk(1,Inf) ;
NC = nargin ;
% check if we should flip the order
if ischar(varargin{end}) && (strcmpi(varargin{end},'matlab') || strcmpi(varargin{end},'john'))
% based on a suggestion by JD on the FEX
NC = NC-1 ;
ii = 1:NC ; % now first argument will change fastest
else
% default: enter arguments backwards, so last one (AN) is changing fastest
ii = NC:-1:1 ;
end
args = varargin(1:NC) ;
% check for empty inputs
if any(cellfun('isempty',args))
warning('ALLCOMB:EmptyInput','One of more empty inputs result in an empty output.') ;
A = zeros(0,NC) ;
elseif NC > 1
isCellInput = cellfun(@iscell,args) ;
if any(isCellInput)
if ~all(isCellInput)
error('ALLCOMB:InvalidCellInput', ...
'For cell input, all arguments should be cell arrays.') ;
end
% for cell input, we use to indices to get all combinations
ix = cellfun(@(c) 1:numel(c), args,'un',0) ;
% flip using ii if last column is changing fastest
[ix{ii}] = ndgrid(ix{ii}) ;
A = cell(numel(ix{1}),NC) ; % pre-allocate the output
for k=1:NC
% combine
A(:,k) = reshape(args{k}(ix{k}),[],1) ;
end
else
% non-cell input, assuming all numerical values or strings
% flip using ii if last column is changing fastest
[A{ii}] = ndgrid(args{ii}) ;
% concatenate
A = reshape(cat(NC+1,A{:}),[],NC) ;
end
elseif NC==1
A = args{1}(:) ; % nothing to combine
else % NC==0, there was only the 'matlab' flag argument
A = zeros(0,0) ; % nothing
end
%% license.txt
% Copyright (c) 2016, Jos (10584)
% All rights reserved.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are
% met:
%
% * Redistributions of source code must retain the above copyright
% notice, this list of conditions and the following disclaimer.
% * Redistributions in binary form must reproduce the above copyright
% notice, this list of conditions and the following disclaimer in
% the documentation and/or other materials provided with the distribution
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
% POSSIBILITY OF SUCH DAMAGE.
end