【问题标题】:Average data in multiple excel file using MATLAB使用MATLAB的多个excel文件中的平均数据
【发布时间】:2014-03-01 12:31:00
【问题描述】:

我有多个 excel 文件,如下所示(每小时数据)。我想获得每日平均值(例如从17:00到第二天16:00)。我只知道一点Matlab。目前我的解决方案如下,但出现了一些问题。

  1. 读取每个 excel 文件并将数据存储在一个变量中。
  2. 将所有数据合并到一个变量中。
  3. 找到 17:00 的行号 (n)。为此,我获取了每一行的 datenum,然后只搜索(找到)对应于 17:00 的 datenum。
  4. 平均每两行之间的数据 (n(i))。

如果原始数据正确,它就可以正常工作。但问题如下。

  1. 17:00 的某些数据丢失。所以当它试图找到 17:00 的行时会出错。
  2. 当我有超过 100 个 excel 文件时,它运行非常非常慢。

谁能给一些建议如何解决这个问题?我更喜欢使用 Matlab,因为它是我唯一了解的工具。非常感谢!

编辑 1:提供的代码

以下是获取每日平均值的代码。我已经合并了文件“summary_file.xls”中的所有数据(这部分的代码没有显示。

如下所示的示例表。

  1. 9 月 1 日至 9 月 2 日 17:00 之间的时间平均值没有问题。
  2. 对于缺少数据的日子,我想获取 17:00 之前所有可用数据的平均值。
  3. 示例:由于缺少 9 月 3 日 17:00 的数据,因此无法获得 9 月 2-3 日的平均值。对于这种情况,我想获取 17:00 之前(即 9 月 3 日 9:00 之前)所有数据的平均值
  4. 那么对于 9 月 3-4 日,我想计算从 18:00 开始的平均值。
  5. 对于所有数据缺失的日子,只需将所有数据设为 0 或标记为不可用。

[num,txt,raw] = xlsread('summary_file.xls'); % 读取文件

date_num = num(:,11); % read the column containing date number
starting = '2003/09/05-17:00'; %  starting time
starting = datenum(starting,formatIn_2); % convert starting time to date number
ending = '2003/09/09-17:00';%  ending time
ending = datenum(ending,formatIn_2); %convert ending time to date number

s = starting:1:ending; % All date number with 17:00

%% find the row number with 17:00
for i = 1:ending-starting+1
    [a(i) b(i)] = find(date_num==s(i));
end
%% Store the averaged data in variable p
for i = 1:ending-starting
    p(i,:) = mean(num(a(i):a(i+1)-1,:));
end

样本输入数据 -

+------+-------+----------+-------+-------+------- +-------+-------+--------+ | 2003 | 1-9月| 15:00 | 100.2 | 29 | 70.5 | 3.903 | 728 | 0 | +------+-------+----------+-------+-------+------- +-------+-------+--------+ | 2003 | 1-9月| 16:00 | 100.1 | 29.31 | 70.7 | 4.328 | 611.8 | 0 | | 2003 | 1-9月| 17:00 | 100.1 | 29.64 | 67.06 | 3.719 | 434.8 | 0 | | 2003 | 1-9月| 18:00 | 100.1 | 29.67 | 64.4 | 3.005 | 172.4 | 0 | | 2003 | 1-9月| 19:00 | 100.1 | 29.06 | 68.22 | 2.292 | 19.89 | 0 | | 2003 | 1-9月| 20:00 | 100.2 | 28.43 | 74.7 | 2.436 | 0.428 | 0 | | 2003 | 1-9月| 21:00 | 100.2 | 27.92 | 76.2 | 1.931 | 0.006 | 0 | | 2003 | 1-9月| 22:00 | 100.3 | 27.67 | 77.3 | 1.825 | 0.007 | 0 | | 2003 | 1-9月| 23:00 | 100.4 | 27.55 | 77.9 | 1.622 | 0.007 | 0 | | 2003 | 1-9月| 24:00:00 | 100.4 | 27.69 | 77.8 | 0.863 | 0.008 | 0 | | 2003 | 9 月 2 日 | 1:00 | 100.4 | 27.55 | 78.3 | 0.879 | 0.008 | 0 | | 2003 | 9 月 2 日 | 2:00 | 100.3 | 27.05 | 82.1 | 1 | 0.016 | 0.762 | | 2003 | 9 月 2 日 | 3:00 | 100.3 | 26.41 | 86.8 | 0.805 | 0.006 | 0 | | 2003 | 9 月 2 日 | 4:00 | 100.2 | 26.6 | 85.5 | 0.522 | 0.011 | 0.508 | | 2003 | 9 月 2 日 | 5:00 | 100.2 | 25.53 | 83.8 | 2.158 | 0.011 | 0 | | 2003 | 9 月 2 日 | 6:00 | 100.3 | 24.5 | 86.6 | 2.711 | 0.016 | 0 | | 2003 | 9 月 2 日 | 7:00 | 100.4 | 24.85 | 86.9 | 2.562 | 0.016 | 4.318 | | 2003 | 9 月 2 日 | 8:00 | 100.6 | 21.11 | 94 | 8.15 | 9.96 | 26.67 | | 2003 | 9 月 2 日 | 9:00 | 100.6 | 22.23 | 91.9 | 5.065 | 31.67 | 0.254 | | 2003 | 9 月 2 日 | 10:00 | 100.6 | 23.51 | 88.8 | 5.742 | 39.16 | 0.254 | | 2003 | 9 月 2 日 | 11:00 | 100.6 | 24 | 87.7 | 4.494 | 97.8 | 0 | | 2003 | 9 月 2 日 | 12:00 | 100.6 | 24.69 | 85.3 | 4.709 | 142.2 | 0 | | 2003 | 9 月 2 日 | 13:00 | 100.5 | 25.57 | 82.8 | 5.66 | 259.1 | 0 | | 2003 | 9 月 2 日 | 14:00 | 100.4 | 25.69 | 81.9 | 5.634 | 157.5 | 0 | | 2003 | 9 月 2 日 | 15:00 | 100.3 | 26.18 | 79.1 | 5.564 | 308.2 | 0 | | 2003 | 9 月 2 日 | 16:00 | 100.3 | 26.08 | 78.3 | 6.283 | 135.3 | 0 | | 2003 | 9 月 2 日 | 17:00 | 100.3 | 25.75 | 81.2 | 4.595 | 55.68 | 0.762 | | 2003 | 9 月 2 日 | 18:00 | 100.3 | 25.01 | 84.5 | 4.843 | 55.21 | 1.778 | | 2003 | 9 月 2 日 | 19:00 | 100.3 | 25.15 | 86.1 | 1.433 | 22.43 | 0 | | 2003 | 9 月 2 日 | 20:00 | 100.3 | 24.98 | 86.1 | 1.985 | 0.301 | 0 | | 2003 | 9 月 2 日 | 21:00 | 100.3 | 24.75 | 85.1 | 0.712 | 0.009 | 0 | | 2003 | 9 月 2 日 | 22:00 | 100.4 | 24.76 | 85.3 | 1.546 | 0.011 | 0 | | 2003 | 9 月 2 日 | 23:00 | 100.5 | 24.92 | 84.5 | 1.186 | 0.008 | 0 | | 2003 | 9 月 2 日 | 24:00:00 | 100.5 | 24.96 | 84.9 | 1.31 | 0.007 | 0 | | 2003 | 3 月 | 1:00 | 100.5 | 25 | 85.3 | 0.702 | 0.012 | 0 | | 2003 | 3 月 | 2:00 | 100.5 | 24.99 | 86 | 0.35 | 0.017 | 0 | | 2003 | 3 月 | 3:00 | 100.4 | 25.07 | 86.1 | 0.69 | 0.008 | 0 | | 2003 | 3 月 | 4:00 | 100.3 | 24.92 | 86.5 | 1.347 | 0.011 | 0 | | 2003 | 3 月 | 5:00 | 100.3 | 25.27 | 85.5 | 0.834 | 0.009 | 0 | | 2003 | 3 月 | 6:00 | 100.3 | 24.97 | 86.9 | 0.627 | 0.012 | 0 | | 2003 | 3 月 | 7:00 | 100.3 | 24.8 | 87.7 | 0.755 | 0.108 | 0 | | 2003 | 3 月 | 8:00 | 100.4 | 25.54 | 85 | 0.202 | 37.11 | 0 | | 2003 | 3 月 | 9:00 | 100.4 | 26.72 | 81 | 1.853 | 219.4 | 0 | | 2003 | 3 月 | 18:00 | 100.2 | 29.67 | 56.39 | 2.856 | 456.2 | 0 | | 2003 | 3 月 | 19:00 | 100.2 | 30.17 | 53.66 | 2.204 | 266 | 0 | +-----+-------+----------+-------+-------+------- +-------+-------+--------+

【问题讨论】:

    标签: excel matlab average missing-data


    【解决方案1】:

    以下代码可能满足您的要求。同样,由于您对每日平均值感兴趣,因此输出会小得多,因为它超过 24 小时,我假设您需要它。此外,它还会处理您丢失数据的情况。

    代码 -

    %% Setup params and data
    start_hour = 17;
    [num,txt,raw] = xlsread('summary_file.xls');
    
    datenums = NaN(size(num,1),1);
    for count = 1:size(num,1)
        year1 = cell2mat(raw(count,1));
        date1 = cell2mat(raw(count,2));
        time1 = cell2mat(raw(count,3));
        date_str = strcat( num2str(year1) , '-', date1 );
        datenums(count) = datenum( date_str, 'yyyy-dd-mmm')  + time1(:);
    end
    
    %% Take care of conditions
    firstdata_start_hour = round(24*cell2mat(raw(1,3)));
    if firstdata_start_hour > 17
        start1 =  floor(datenums(1))  + (start_hour/24);
    elseif firstdata_start_hour < 17
        start1 =  floor(datenums(1))-1  + (start_hour/24);
    else
        start1 = datenums(1);
    end
    
    ind1 = floor(datenums-start1) + 1;
    
    %% Start Processing
    num_items = size(num,2)-3;
    num_days = max(ind1);
    
    bins = NaN(num_days,num_items);
    for count1 = 1:size(bins,2)
        for count2 = 1:size(bins,1)
            bins(count2,count1) = mean(num(find(ind1==count2),count1+3));
        end
    end
    bins(isnan(bins))=0;
    average_nums = bins
    

    输出一些数据的平均值,由 OP 根据我的要求编译 -

    +-----------+---------------+------+-------------+------------+-----------+--------------+
    |   Date    | Pressure(kPa) | Temp | Humidity(%) | W-spd(m/s) | Radiation | Rainfall(mm) |
    +-----------+---------------+------+-------------+------------+-----------+--------------+
    | 8/10/2009 | 100.1         | 25.8 | 79.1        | 1.4        | 82.6      | 1.7          |
    | 8/11/2009 | 100.2         | 27.5 | 75.7        | 1.9        | 173.8     | 0.0          |
    | 8/12/2009 | 100.1         | 28.4 | 73.5        | 2.1        | 177.1     | 0.0          |
    | 8/13/2009 | 100.0         | 28.4 | 73.2        | 2.5        | 197.4     | 0.0          |
    | 8/14/2009 | 100.0         | 28.5 | 73.5        | 2.2        | 151.2     | 0.0          |
    | 8/15/2009 | 100.2         | 27.3 | 75.4        | 1.2        | 96.2      | 0.4          |
    | 8/16/2009 | 100.2         | 27.1 | 75.5        | 1.4        | 122.6     | 0.0          |
    | 8/17/2009 | 100.2         | 27.2 | 75.7        | 1.5        | 158.3     | 0.2          |
    | 8/18/2009 | 100.2         | 27.5 | 72.2        | 1.4        | 186.4     | 0.0          |
    | 8/19/2009 | 100.3         | 28.4 | 68.4        | 1.9        | 186.9     | 0.0          |
    | 8/20/2009 | 100.3         | 28.1 | 69.2        | 2.0        | 184.8     | 0.0          |
    | 8/21/2009 | 100.3         | 26.5 | 75.8        | 1.3        | 122.3     | 0.6          |
    +-----------+---------------+------+-------------+------------+-----------+--------------+
    

    对于多个 excel 文件,您必须循环遍历所有此类文件。似乎没有其他出路。

    【讨论】:

    • 非常感谢!上面的代码效果很好!但是第 9 行中的 'time1(:)' 需要修改为 'time1(:)/24'。对吗?
    • 读入time1 - "time1 = cell2mat(raw(count,3));"后,检查time1的值。如果它们是分数,不要使用除以 24,否则使用它。在我的系统上,它以分数形式读取,因此我不需要除以 24。我怀疑这可能是您创建 XLS 工作表或 MATLAB 版本本身的方式的问题。
    • 考虑对有用的答案进行投票。不仅可以为公认的答案,也可以为其他人这样做。在这里阅读更多 - stackoverflow.com/help/privileges/vote-up
    • 谢谢!确认时间 1 不是分数,因此需要除以 24。我也想投票给答案,但我目前没有足够的声誉(15)。在我有足够的声誉之后我会这样做。
    • 另外,如果您能够设法以表格形式显示输出平均值/平均值,类似于您显示输入数据的方式,那么展示结果会很不错!如果你能做到这一点,建议我在我的答案中进行编辑!
    【解决方案2】:

    当您使用 Matlab 的 xlsread 时,它会打开和关闭 Excel COM 服务器,因此对多个文件使用它会减慢执行速度。阅读 Matlab Central 的 this post,其中解释了如何避免打开和关闭 Excel COM Server。

    至于缺失的数据,或许你可以用find(time&lt;17:00,'last')find(time&gt;17:00,'first')的数据插值17:00

    【讨论】:

    • 谢谢!对于 xlasread,我会阅读您推荐的帖子。对于缺失的数据,我在问题中添加了更多信息(编辑 1),你能帮忙看看吗?
    • 如果你能坚持basic模式,我认为它不会使用com服务器。
    【解决方案3】:

    我喜欢使用 MATLAB,但如果您不介意我问,您是否考虑过使用 R 统计软件包?在我看来,这真的很酷,你不必同意我的观点。

    完成您要求的任务非常容易。 R 甚至可以处理丢失的数据并轻松解决它,并且可以轻松读取 excel 文件并搜索您想要的数据。

    在哪里获得 R:

    http://cran.r-project.org/

    【讨论】:

    • 谢谢!我也对使用 R 很感兴趣。但是我没有足够的时间来学习用于这项任务的新软件。可能以后我可以把它捡起来。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-01
    • 1970-01-01
    • 2018-03-16
    • 2015-06-30
    • 1970-01-01
    • 2012-06-25
    • 1970-01-01
    相关资源
    最近更新 更多