Matlab 查找事件的平均或中间日期

Matlab 查找事件的平均或中间日期,matlab,date,Matlab,Date,我有一个数据集,我提取了事件发生的日期。日期的格式为MMDDYY,尽管MatLab通常不显示前导零,而是MDDYY 是否有一种方法可以找到平均值或中位数(我可以使用其中任何一种)日期中值在天数为奇数的情况下可以正常工作,但对于偶数,我认为是将中间的两个天数取平均值,这不会产生合理的值。我一直在尝试使用regexp将日期转换为MatLab格式,并将其重新组合在一起,但我没有让它工作。谢谢 dates=[32381 41081 40581 32381 32981 41081 40981

我有一个数据集,我提取了事件发生的日期。日期的格式为MMDDYY,尽管MatLab通常不显示前导零,而是MDDYY


是否有一种方法可以找到平均值或中位数(我可以使用其中任何一种)日期<代码>中值在天数为奇数的情况下可以正常工作,但对于偶数,我认为是将中间的两个天数取平均值,这不会产生合理的值。我一直在尝试使用
regexp
将日期转换为MatLab格式,并将其重新组合在一起,但我没有让它工作。谢谢

dates=[32381 41081  40581  32381  32981 41081   40981  40581];

将日期存储为YYMMDD,而不是MMDDYY。这有一个有用的副作用,即日期的数字顺序也是时间顺序

下面是您可以编写的函数的伪代码

foreach date:
    year = date % 100
    date = (date - year) / 100
    day = date % 100
    date = (date - day) / 100
    month = date
    newdate = year * 100 * 100 + month * 100 + day
end for
一旦您有了YYMMDD格式的日期,然后找到中位数(数字),这也是按时间顺序排列的中位数。

您可以使用将日期转换为序列日期号(1在01/01/0000,2在02/01/0000,367在01/01/0001,等等):

然后可以对这些日期数字执行任何算术运算,如取平均值或中位数:

mean(numDates)
median(numDates)
这里唯一的问题是,日期不是字符串类型,而是数字。幸运的是,datenum也接受数字输入,但您必须以向量形式给出日期、月份和年份:

numDate = datenum([year month day])
或者,如果有多个时间戳,则作为矩阵中的行

因此,对于您指定的示例数据:

dates=[32381 41081  40581  32381  32981 41081   40981  40581];
years  = mod(dates,100);
dates  = (dates-years)./100;
days   = mod(dates,100);
months = (dates-days)./100;
years = years + 1900; % set the years to the 20th century

numDates = datenum([years(:) months(:) days(:)]);
fprintf('The mean date is %s\n', datestr(mean(numDates)));
fprintf('The median date is %s\n', datestr(median(numDates)));

在本例中,我使用将结果的平均值和中值转换回可读的日期格式,该格式以序列日期号作为输入。

您可以在上面看到如何将日期表示为数字

我不会在你的问题上加上寻找名单中位数的问题。当值为偶数时,默认的matlab
median
函数将平均两个中间值

但是你可以自己做!试试这个:

dates; % is your array of dates in numeric form
sdates = sort(dates);
mediandate = sdates(round((length(sdates)+1)/2));
试试这个:

dates; % is your array of dates in numeric form
sdates = sort(dates);
mediandate = sdates(round((length(sdates)+1)/2));
dates=[32381 41081 40581 32381 32981 41081 40981 40581];
d=zeros(1,length(dates));
for i=1:length(dates)
    d(i)=datenum(num2str(dates(i)),'ddmmyy');
end
m=mean(d);
m_str=datestr(m,'dd.mm.yy')

我希望这些信息有用,因为

“我一直在尝试将日期转换为MatLab格式”。。。你到底试过什么?您是否意识到
x%100
floor(x/100)
足以将数字拆分为YY、DD和M或MM?对不起,没有。x%100做什么?我不熟悉%的用法。是的,但是arne.b使用的是美元符号,就像它通常使用的那样:模运算符。但是,在matlab中,模运算符不存在,您必须使用模函数“mod”,感谢@GuntherStruyf我从未听说过模运算符,并且被arne.b和Dan Nissenbaum在其解决方案中使用的
%
所迷惑,但现在它有意义了。我在MATLAB上看了太久,没有意识到一个简单的
/10^x
可以把数字分开!比拆分为stringoops简单多了抱歉。我把语言弄糊涂了。正如Gunther所说,我指的是mod函数。直到@GuntherStruyf对模运算符发表评论,我才明白这一点。MATLAB使用
mod()
而不是
%
。谢谢你的建议。谢谢你完整的回答。我应该提到我知道datenum和datestr,但我不知道如何将日期转换成MATLAB可以识别的形式。谢谢!我认为这将是最容易使用的,尽管使用
mmddyy
。。。疯狂的美国人和他们的伪标准:)不,它不起作用。我也是我的第一个朋友,但由于缺少零,这一切都搞砸了;因此,1052012被翻译为2012年5月10日,而不是2012年5月1日:/看起来它可能适用于MMDDYY或MDDYY的情况,而不是您刚才所说的DDMMYY。可能纯粹是巧合,但是
datestr(datenum(num2str('10512','mmddyy'))
生成2012年5月1日,但不幸的是,您似乎无法使用dates(:)来生成整个数组。我希望我能用一行:
datestr(median(datenum)(num2str(dates(:),'mmddyy')))
mmz,我可能错了。我在测试倍频程,它的行为就像我在第一次评论中说的那样。现在在matlab中进行测试时,我发现matlab本身并没有犯这样的错误@多米尼克:你错放了一个钩子
datestr(平均值(datenum)(num2str(dates(:),'mmddyy')))
doeswork(在matlab中)。为了将来的参考,(速度)和良好的实践,我仍然会使用我的答案:假设优点是我可以四舍五入到最近的一天?这与
轮(中位数(日期))
有何不同?你担心我会想出一个不在你的日期列表中的中位数日期。这会使您尽可能接近所需的中值,并且列表中仍有日期。这可能有用的地方:也许你需要列出一个工作日,所以你的列表中只有工作日。这肯定会给你一个工作日。