问题描述
我有一个大约 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
编辑: 我像这样打开文件:
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');
(第 1 个月不太正确,因为第 1 个月有两个电子支付条目,但是在绘图之前,您可以做不同的事情来按月等对数据求和。