MATLABUNIQUE,在matlab里找一个矩阵全是0的那一列或行?
例如a=[123;000;234;000;789];从中我们可以看出都为0的是第2行和第4行。首先我们可以按行从小到大排列,全是0的必定是第一行[C,ia,ic]=unique(a,'rows');所以从ic数列中寻找为数字为1的即为所求find(ic==1)>>find(ic==1)ans=24
离散型随机变量的联合分布率怎么算?
给定至少两个随机变量X,Y,…, 它们的联合概率分布(Joint probability distribution)指的是每一个随机变量的值落入特定范围或者离散点集合内的概率. 对于只有两个随机变量的情况, 称为二元分布(bivariate distribution).
联合概率分布可以使用联合累计分布函数(joint cumulative distribution function), 连续随机变量的联合概率密度函数(joint probability density function)或者离散变量的联合概率质量函数(joint probability mass function)来描述. 由此又衍生出两个概念: 边缘分布(marginal distribution)和条件概率分布(conditional probability distribution).
二. 离散变量的联合概率质量函数公式
公式:

是给定X=xX=x的Y=yY=y的条件概率.
而且有:

如果XX和YY相互独立:

如果XX和YY条件不独立(conditionally dependent):
P(X=x and Y=y)=P(X=x)⋅P(Y=y|X=x)P(X=x and Y=y)=P(X=x)·P(Y=y|X=x)
也可以使用联合累计分布函数的差分来计算:
联合累计分布函数定义是:

所以F(x,y)F(x,y)的导数(差分)就是P(X=x and Y=y)P(X=x and Y=y)
三. 使用Matlab计算离散2D联合分布
参考: Calculating a 2D joint probability distribution
离散2D联合分布可用于计算两张图片的互信息MI.
0. 定义两个离散的随机变量.
有N个点分布在边长为1的正方形区域内. 把正方形分为K1*K2的小矩形. 统计每个小矩形内的点的个数.
% Data
N = 1e5; % number of points
xy = rand(N, 2); % coordinates of points
xy(randi(2*N, 100, 1)) = 0; % add some points on one side
xy(randi(2*N, 100, 1)) = 1; % add some points on the other side
xy(randi(N, 100, 1), :) = 0; % add some points on one corner
xy(randi(N, 100, 1), :) = 1; % add some points on one corner
inds= unique(randi(N, 100, 1));
xy(inds, :) = repmat([0 1], numel(inds), 1); % add some points on one corner
inds= unique(randi(N, 100, 1));
xy(inds, :) = repmat([1 0], numel(inds), 1); % add some points on one corner
% Intervals for rectangles
K1 = ceil(sqrt(N/5)); % number of intervals along x
K2 = K1; % number of intervals along y
int_x = [0:(1 / K1):1]; % intervals along x
int_y = [0:(1 / K2):1]; % intervals along y
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1. 从定义出发, 使用for循环:
tic
count_cells = zeros(K1, K2);
for k1 = 1:K1
inds1 = (xy(:, 1) >= int_x(k1)) & (xy(:, 1) < int_x(k1 + 1));
for k2 = 1:K2
inds2 = (xy(:, 2) >= int_y(k2)) & (xy(:, 2) < int_y(k2 + 1));
count_cells(k1, k2) = sum(inds1 .* inds2);% 布尔相乘得到交集点的个数
end
end
toc
% Elapsed time is 39.357691 seconds.
1
2
3
4
5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11
可见使用两重循环的计算时间非常长.
2. 使用hist3函数
N=hist3(X,'Edges',edges)是matlab中专门计算二元分布的函数.
edges是包含两个递增array的cell. 第一维分组edge1是edges{1}, 第二维分组edge2是edges{2}.
也就是:
edges1(i)<=X(k,1)<edges1(i+1)edges1(i)<=X(k,1)<edges1(i+1)
edges2(j)<=X(k,2)<edges2(j+1)edges2(j)<=X(k,2)<edges2(j+1)
正好落在edges1(i+1)edges1(i+1)或者edges2(j+1)edges2(j+1)上的点的个数放在N的最后一行或者最后一列.
hist3不统计edges范围外的部分.
N是一个二维矩阵, 统计的落到每个单元格内的点的个数.
tic
count_cells_hist = hist3(xy, 'Edges', {int_x int_y});
% 注意hist3得到的矩阵是K1+1*K2+1的, 所以把最后一行和一列去掉.
% 最后一行或一列表示的是 X(k,1)= edges{1}(end)或者X(k,2) = edges{2}(end)的点数
count_cells_hist(end, :) = []; count_cells_hist(:, end) = [];
toc
all(count_cells(:) == count_cells_hist(:))
% Elapsed time is 0.017995 seconds.
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
显然比用两重for循环快多了.
3. 使用矩阵二元操作bsxfun
C = bsxfun(fun,A,B)对A和B做逐个元素的二元操作, 操作由函数 fun指定.
返回的C中, 1表示满足条件, 0 表示不满足条件. 可用的fun有:
fun operation
@plus Plus
@minus Minus
@timesArray multiply
@rdivideRight array divide
@ldivideLeft array divide
@power Array power
@max Binary maximum
@min Binary minimum
@rem Remainder after division
@mod Modulus after division
@atan2 Four-quadrant inverse tangent; result in radians
@atan2d Four-quadrant inverse tangent; result in degrees
@hypot Square root of sum of squares
@eq Equal
@neNot equal
@ltLess than
@le Less than or equal to
@gt Greater than
@ge Greater than or equal to
@andElement-wise logical AND
@orElement-wise logical OR
@xorLogical exclusive OR
使用bsxfun的matlab代码:
%% bsxfun
tic
xcomps = single(bsxfun(@ge,xy(:,1),int_x));% 10000*143矩阵
ycomps = single(bsxfun(@ge,xy(:,2),int_y));% 10000*143矩阵
% 相当于求CDF
count_again = xcomps.' * ycomps; %' 143x143 = 143x1e5 * 1e5x143
% 差分后是142*142
count_again_fix = diff(diff(count_again')');
toc
% Elapsed time is 0.178316 seconds.
all(count_cells_hist(:) == count_again_fix(:))
1
2
3
4
5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11
bsxfun稍逊于hist3, 可以针对没有statistics toolbox的情况下使用.
4. 使用accumarray
A= accumarray(subs,val)使用subs的元素值作为索引. subs和val是一一对应的. 将subs中相同值对应的val值累加. 也就是说, subs中元素的位置决定了val哪些元素相加, subs中元素的值决定了累加值在输出中的位置. 看matlab help中示例:
Example 1
Create a 5-by-1 vector and sum values for repeated 1-D subscripts:
val = 101:105;
subs = [1; 2; 4; 2; 4];
A = accumarray(subs, val)
A =
101 % A(1) = val(1) = 101
206 % A(2) = val(2)+val(4) = 102+104 = 206
0 % A(3) = 0
208 % A(4) = val(3)+val(5) = 103+105 = 208
subs中元素值必须是正整数值. 所以在表示分组时, 可以把[0,1]区间变为[1,K1]区间. matlab代码:
%%%%% 第五种方法Using accumarray
% Another approach is to use accumarray to make the joint histogram after we bin the data.
% Starting with int_x, int_y, K1, xy, etc.:
tic
% take (0,1) data onto [1 K1], following A.Dondas approach for easy comparison
ii = floor(xy(:,1)*(K1-eps))+1;
ii(ii<1) = 1; ii(ii>K1) = K1;
jj = floor(xy(:,2)*(K1-eps))+1;
jj(jj<1) = 1; jj(jj>K1) = K1;
% create the histogram and normalize
H = accumarray([ii jj],ones(1,size(ii,1)));
PDF = H / size(xy,1); % for probabilities summing to 1
toc
% Elapsed time is 0.006356 seconds.
all(count_cells_hist(:) == count_again_fix(:))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ms级别! 真是快!
5. 使用mex编译
mex混合编程参考: 在Matlab中使用mex函数进行C/C++混合编程
#include "mex.h"
// http://stackoverflow.com/questions/19745917/calculating-a-2d-joint-probability-distribution
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
unsigned long int hh, ctrl; /* counters */
unsigned long int N, m, n; /* size of matrices */
unsigned long int *xy; /* data */
unsigned long int *count_cells; /* joint frequencies */
/* matrices needed */
mxArray *count_cellsArray;
/* Now we need to get the data */
if (nrhs == 3) {
xy = (unsigned long int*) mxGetData(prhs[0]);
N = (unsigned long int) mxGetM(prhs[0]);//取矩阵的行数
m = (unsigned long int) mxGetScalar(prhs[1]);
n = (unsigned long int) mxGetScalar(prhs[2]);
}
/* Then build the matrices for the output */
count_cellsArray = mxCreateNumericMatrix(m + 1, n + 1, mxUINT32_CLASS, mxREAL);
count_cells = mxGetData(count_cellsArray);
plhs[0] = count_cellsArray;
hh = 0; /* counter for elements of xy */
/* for all points from 1 to N */
for(hh=0; hh<N; hh++) {
ctrl = (m + 1) * xy[N + hh] + xy[hh];
count_cells[ctrl] = count_cells[ctrl] + 1;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
将代码保存为: joint_dist_points_2D.c. 在matlab cmd中运行:
mex joint_dist_points_2D.c
1
1
生成joint_dist_points_2D.mexw32文件.
matlab调用代码:
% Use mex function
tic
xy2 = uint32(floor(xy ./ repmat([1 / K1, 1 / K2], N, 1)));
count_cells = joint_dist_points_2D(xy2, uint32(K1), uint32(K2));
toc
% Elapsed time is 0.011696 seconds.
1
2
3
4
5
6
1
2
3
4
5
6
也是非常快的.
mathlab由小到大怎么编写?
1/6 分步阅读
第一步在我们的电脑上打开matlab命令行窗口,输入“A=[1 3 2 6 4 8 1 12]”,按回车键创建一个一维数组A
2/6
第二步输入“sort(A)”,这是将数据从小到大排列,按回车键
3/6
第三步输入“sort(A,'descend')”,这是将数据从大到小排列,按回车键
4/6
第四步如果我们需要知道数据排序前的序号,输入“[B,index]=sort(A)”,B是排序后的数据,index是数字排序前的序号
5/6
第五步按回车键之后,可以看到B和index的值,
6/6
第六步如果我们对多维数组进行排序的话,输入sort(A),会对每列进行排序
matlab筛选向量的不重复值?
A=矩阵;
b1=cells(55,1);
for i=1:10
c=setdiff(A(:,i),b1);
b=unique(c);
[x,y]=ismember(b,A(:,i)) ;
b1(x)=A(x,i);
end
你见过的excel最牛和最low用法是什么?
Excel中最牛的用法,一定那些可以轻松用于解决实际工作中的大问题的功能,而不是那些只是看起来很牛,而学不会或用不来的东西,因为那个跟你没有关系,或者说对你来说没有意义。因此,我现在非常推荐大家在学好Excel基础功能的情况下,加紧对Excel2016新功能(Excel2010或Excel2013可到微软官方下载相应的插件)的学习,不仅超级强大,而且十分简单易学。举例如下:
Power Query秒解顾客最后消费记录神难题小勤:大海,为提高顾客服务体验,公司现在要求除了将顾客的所有消费记录提出来外,还要求将顾客的最后一次消费记录提取出来,发给现场的销售人员,方便他们提供更好的服务。
大海:鹅……厉害了噢。开始这么高级的服务了。
小勤:是啊,但我就惨了,每天数据都在增加,每天出报表……
大海:这个问题啊,以前有些大神专门研究过,还写过不少神公式,给你看看:
还有最后消费金额的公式:
小勤:晕啊。这么复杂。
大海:真说起来,这个公式的复杂程度其实不算个大问题,更麻烦的是这个公式涉及数据量大的时候,计算起来会很卡。
小勤:那怎么办好呢?
大海:现在有PowerQuery,秒解,简单到没朋友,看啊。
Step-1:获取数据
Step-2:反转行
Step-3:对姓名列删除重复项
Step-4:再次反转行(如不需要保持原数据顺序,此步骤可省略)
Step-5:数据上载
小勤:666!只要点2下就好了!
大海:你说呢?以后新订单数据进来就刷一下。
小勤:嗯。这太好了,要不能这样的话,公司要真靠数据来提升服务水平可太难了。
大海:的确,服务的提升必须要有最新的数据来保证,这就是快速(敏捷)数据分析的价值啊。
Power Query:2步搞定数据转换神难题小勤:大海,刚有个同事在问我这种情况怎么办!公式怎么写啊?
大海:为什么又要公式?
小勤:还有大批量数据都需要做这样的迁移啊。公式不是更加自动一点吗?
大海:PowerQuery不是更加自动吗?第一反应为什么不是用Power Query?
小勤:鹅……对哦!Power Query是可以整合、转换数据,并可以自动刷新的。
大海:嗯。就这个问题来说,去掉数据获取(导入)、数据上载头尾两个简单步骤后,用Power Query只要2步就搞定了:逆透视后再透视。
Step-0:数据获取
Step-1:逆透视
Step-2:透视
最后,数据上载
小勤:真是太简单了!那如果写公式的话呢?
大海:公式的话可以看作多条件求和或多行列数据匹配的情况考虑,比如用sumifs、sumproduct、if+index+match等组合的方式,但都比较复杂,而且有个前提:业务经理、月份、存货分类等行列标题的内容要先生成,即结果表的框架先生成,只用公式读取其中的数值内容。如果要连行列标题(业务经理、月份、存货分类)都要靠公式整出来的话,基本没救。
小勤:好吧。有合适的工具,掌握有效的技能,真是事半功倍啊!
更多Power Query精彩实战案例可以用Power Query来轻松迅速解决的Excel问题举不胜举,我曾经分享过一系列的实战案例,供参考:
【私信“材料”直接下载系列训练材料】【Excel必备基础小动画】
【60+函数汇总案例】
【数据透视基础精选10篇】
【Power Query入门到实战80篇】
【Power Pivot 基础精选15篇】
我是大海,微软认证Excel专家,企业签约Power BI顾问让我们一起学习,共同进步!
还没有评论,来说两句吧...