将矩阵中的日常数据存储在另一个矩阵八度/ matlab中

问题描述

我有一个大约 80 万行的巨大矩阵。 (这只是一小部分,所以你可以看到它是如何制作的)来自每天、一年中每个月的 24 小时数据,一个城市周围大约 7 个收费站。我需要存储在一个新的矩阵中,有多少车是用现金支付的,有多少是使用电子收费设备的,每天,365 天,然后绘制整个过程。在这种情况下,我不必区分通行费,所以我知道我需要第 1,2 8 和 9 列。101 表示现金,106 表示通行费,但老实说,我不知道如何处理这么大的费用矩阵,我是使用八度/matlab 和编程的新手,所以非常感谢您的任何建议

#Month  Day Hour    weekday(1to7)   TollStation Direction   Vehicle type    method of payment   Amount of vehicles
1   1   0   3   1   1   1   106 6
1   1   0   3   1   2   1   106 18
2   4   0   3   2   1   1   101 16
2   5   0   3   2   1   1   106 159
3   17  0   3   2   1   2   106 5
4   15  0   3   2   2   1   101 12
5   19  0   3   2   2   1   106 182
6   1   0   3   3   1   1   106 98
7   1   0   3   3   1   2   106 6
8   1   0   3   3   2   1   106 67
9   1   0   3   3   2   2   106 6
10  1   0   3   4   1   1   106 59
11  1   0   3   4   1   2   106 1
12  1   0   3   4   2   1   106 106

enter image description here

编辑: 我像这样打开文件

file=fopen('FlujoVehicular2019.txt'); %open file
arreglo=fscanf(file,'%i',[9,812513]); %reads file
fclose(file); %close file
M = arreglo';

[nRow,~] = size(M);


elec_rows=find(M(:,1)==1 & M(:,2)==1 & M(:,8)==10); %filters month 1,day 1 electronic payments

>a = sum(M(elec_rows,9)); %sums all electronic payments from month 1 day 1

>disp(a)

现在我需要将这些数据存储在某个地方,然后转到第 1 天第 2 天、第 1 天第 3 天等等。我怎样才能做到这一点?再次感谢

解决方法

因此,800k x 9 很大,但并不是“那么大”。 Matlab/Octave 处理这么多数据应该没问题。

例如 - 在 Octave 上,创建一个随机的 800,000 x 9 数组:

>> a = rand(800000,9);

>> whos 
Variables visible from the current scope:

variables in scope: top scope

   Attr Name        Size                     Bytes  Class
   ==== ====        ====                     =====  =====
        a      800000x9                   57600000  double

Total is 7200000 elements using 57600000 bytes

没有可衡量的时间。将数据作为文本保存到磁盘,但是,使用

>> csvwrite('testdata.dat',a);

>> b = csvread('testdata.dat');

创建了一个 135MB 的文件,每个文件都需要几分钟。还是蛮好驾驭的。还有一些文件 i/o 函数可能比我上面使用的更快。

所以第一步是读入你的数据。有许多函数可以执行此操作,请参阅 Octave manual on Simple File I/O。使用这些简单函数的主要问题是您的标题行,从您粘贴的数据来看,它有多个字符作为空格。如果它是单个空格、制表符或逗号,那就很简单了。以下工作,使用 dlmread 和空输入 [] 作为分隔符,以便函数自行计算出来,并指定跳过 1 行和 0 列数据:

>> mydata = dlmread('testdata2.txt',[],1,0);  
warning: implicit conversion from null_matrix to sq_string
mydata =

     1     1     0     3     1     1     1   106     6
     1     1     0     3     1     2     1   106    18
     2     4     0     3     2     1     1   101    16
     2     5     0     3     2     1     1   106   159
     3    17     0     3     2     1     2   106     5
     4    15     0     3     2     2     1   101    12
     5    19     0     3     2     2     1   106   182
     6     1     0     3     3     1     1   106    98
     7     1     0     3     3     1     2   106     6
     8     1     0     3     3     2     1   106    67
     9     1     0     3     3     2     2   106     6
    10     1     0     3     4     1     1   106    59
    11     1     0     3     4     1     2   106     1
    12     1     0     3     4     2     1   106   106

(警告只是关于它处理分隔符的空输入。同样,使用更简单的分隔符会更干净。)还有其他函数也可以工作,包括定义函数识别的输入模式,但 dlmread 似乎可以解决问题。

在将数据读入程序后,一旦您学习了如何使用不同的函数以及 matlab/octave 如何处理索引和逻辑运算符以提取数据子集,您所说的许多其他事情都是相当简单的数据操作。使用整个 800k 线数据集与使用上面包含的小数据集没有什么不同。

举一个例子 - 获取每月支付现金或电子费用的汽车数量:

>> elec_rows=find(mydata(:,8)==106)
elec_rows =

    1
    2
    4
    5
    7
    8
    9
   10
   11
   12
   13
   14

>> cash_rows=find(mydata(:,8)==101)
cash_rows =

   3
   6

>> sum(mydata(elec_rows,9))
ans = 713

>> sum(mydata(cash_rows,9))
ans = 28

和绘图示例:

>> plot(mydata(elec_rows,1),mydata(elec_rows,9),mydata(cash_rows,9));
>> xlabel('month');ylabel('cars');title('cars per month');
>> legend('electronic payment','cash payment');

example data plotting

(第 1 个月不太正确,因为第 1 个月有两个电子支付条目,但是在绘图之前,您可以做不同的事情来按月等对数据求和。