Updated: Randomly adding in rows to a matrix but f

2019-03-06 04:19发布

问题:

The following is a chunk of a much larger Matrix:

     0    1.0000    1.0000   77.0000  100.0000         0    0.2500
     0    1.0000    1.0000   72.0000  100.0000    0.2500    0.2500
     0    1.0000    1.0000   69.0000  100.0000    0.5000    0.2500
     0    1.0000    1.0000   48.0000  100.0000    0.7500    0.2500
1.0000    1.0000    1.0000   65.0000  100.0000    1.0000    0.2500
1.0000    1.0000    1.0000   71.0000  100.0000    1.2500    0.2500
1.0000    1.0000    1.0000   62.0000  100.0000    1.5000    0.2500
1.0000    1.0000    1.0000   41.0000  100.0000    1.7500    0.2500
2.0000    1.0000    1.0000   62.0000  100.0000    2.0000    0.2500
2.0000    1.0000    1.0000   67.0000  100.0000    2.2500    0.2500
2.0000    1.0000    1.0000   71.0000  100.0000    2.5000    0.2500
2.0000    1.0000    1.0000   43.0000  100.0000    2.7500    0.2500
3.0000    1.0000    1.0000   71.0000  100.0000    3.0000    0.2500
3.0000    1.0000    1.0000   62.0000  100.0000    3.2500    0.2500
3.0000    1.0000    1.0000   67.0000  100.0000    3.5000    0.2500
3.0000    1.0000    1.0000   47.0000  100.0000    3.7500    0.2500
4.0000    1.0000    1.0000   69.0000  100.0000    4.0000    0.2500
4.0000    1.0000    1.0000   65.0000  100.0000    4.2500    0.2500
4.0000    1.0000    1.0000   60.0000  100.0000    4.5000    0.2500
4.0000    1.0000    1.0000   41.0000  100.0000    4.7500    0.2500
5.0000    1.0000    1.0000   74.0000  100.0000    5.0000    0.2500
5.0000    1.0000    1.0000   71.0000  100.0000    5.2500    0.2500
5.0000    1.0000    1.0000   65.0000  100.0000    5.5000    0.2500
5.0000    1.0000    1.0000   47.0000  100.0000    5.7500    0.2500

etc.. the Matrix continues from this point in the same fashion:

  • column 1 ascends in 1s every 4 rows: 0-0-0-0-1-1-1-1-2-2-2-2...n-n-n-n
  • column 2 is always 1
  • column 3 is always 1
  • column 4 is grouped in sets of 4 numbers (e.g. [77 72 69 48] is the first set)
  • column 5 is always 100
  • column 6 ascends by 0.25 each row
  • column 7 is always 0.25

In its construction the matrix is grouped in 4 row chunks, each signposted by the ascending number in the first column (0-0-0-0-1-1-1-1-2-2-2-2 etc). For example, the first chunk is:

 0    1.0000    1.0000   77.0000  100.0000         0    0.2500
 0    1.0000    1.0000   72.0000  100.0000    0.2500    0.2500
 0    1.0000    1.0000   69.0000  100.0000    0.5000    0.2500
 0    1.0000    1.0000   48.0000  100.0000    0.7500    0.2500

The length of the full matrix will be around the 1500 mark, let's say: 1512

  • I'd like to insert another row at a random point. It should:

• contain the number 69 in the 4th column

• contain the number 2 in the 3rd column

• contain a value in the 1st column that is +6 from that in the preceding row (i.e. if column 1 in the previous row had the value '3' then I'd want column 1 in the current row to have the value 9)

• contain a value in the 6th column that maintains the pattern of consecutively rising by 0.25 throughout the whole matrix, ie. 0, 0.25. 0.5, 0.75 (and the values in the following rows should be adjusted to continue the pattern as such)

• contain a number 0.25 in the 7th column

  • to make things more complicated I actually want to do this a number of times, rather than just the once - which is to say that throughout the matrix I want to insert lots of single rows that match this description.

  • Each insertion point should be separated from the next by somewhere between 80 to 200 rows of the original matrix. However in each instance the number of rows between 80 and 200 should be randomised (i.e. the first insertion of a row might be after, say, 84 rows on the original matrix, for the next insertion this time it might be after, say, 196 after the first one).

• Crucially, the insertion point should not intersect a 4 note group:

i.e. this is a bad insertion point:

19.0000    1.0000    1.0000   72.0000  100.0000   19.0000    0.2500
19.0000    1.0000    1.0000   67.0000  100.0000   19.2500    0.2500
19.0000    1.0000    1.0000   76.0000  100.0000   19.5000    0.2500
19.0000    1.0000    1.0000   48.0000  100.0000   19.7500    0.2500
20.0000    1.0000    1.0000   65.0000  100.0000   20.0000    0.2500
20.0000    1.0000    1.0000   69.0000  100.0000   20.2500    0.2500
26.0000    1.0000    1.0000   69.0000  100.0000   20.5000    0.2500

But this is fine:

19.0000    1.0000    1.0000   72.0000  100.0000   19.0000    0.2500
19.0000    1.0000    1.0000   67.0000  100.0000   19.2500    0.2500
19.0000    1.0000    1.0000   76.0000  100.0000   19.5000    0.2500
19.0000    1.0000    1.0000   48.0000  100.0000   19.7500    0.2500
20.0000    1.0000    1.0000   65.0000  100.0000   20.0000    0.2500
20.0000    1.0000    1.0000   69.0000  100.0000   20.2500    0.2500
20.0000    1.0000    1.0000   60.0000  100.0000   20.5000    0.2500
20.0000    1.0000    1.0000   45.0000  100.0000   20.7500    0.2500
26.0000    1.0000    1.0000   69.0000  100.0000   21.0000    0.2500
  • For each inserted row: all values in column 1 that follow the insertion row must have 11 added to them.

For example:

19.0000    1.0000    1.0000   72.0000  100.0000   19.0000    0.2500
19.0000    1.0000    1.0000   67.0000  100.0000   19.2500    0.2500
19.0000    1.0000    1.0000   76.0000  100.0000   19.5000    0.2500
19.0000    1.0000    1.0000   48.0000  100.0000   19.7500    0.2500
20.0000    1.0000    1.0000   65.0000  100.0000   20.0000    0.2500
20.0000    1.0000    1.0000   69.0000  100.0000   20.2500    0.2500
20.0000    1.0000    1.0000   60.0000  100.0000   20.5000    0.2500
20.0000    1.0000    1.0000   45.0000  100.0000   20.7500    0.2500
26.0000    1.0000    1.0000   69.0000  100.0000   21.0000    0.2500
32.0000    1.0000    1.0000   64.0000  100.0000   21.2500    0.2500
32.0000    1.0000    1.0000   67.0000  100.0000   21.5000    0.2500
32.0000    1.0000    1.0000   60.0000  100.0000   21.7500    0.2500
32.0000    1.0000    1.0000   36.0000  100.0000   22.0000    0.2500
33.0000    1.0000    1.0000   72.0000  100.0000   22.2500    0.2500
33.0000    1.0000    1.0000   67.0000  100.0000   22.5000    0.2500
33.0000    1.0000    1.0000   64.0000  100.0000   22.7500    0.2500
33.0000    1.0000    1.0000   43.0000  100.0000   23.0000    0.2500
  • Finally.. for every chunk of matrix between an inserted row and the next inserted row (also including the chunk between the matrix beginning and the first inserted row, and the chunk between the last inserted row and the matrix end) I'd like to add to the original values in column 4 a random number between 1 and 12. (as an example (with '2' '9' and '5' in the example being 'random numbers between 1 and 12') 'inserted_row - value+2 - value+2 - value+2 - value+2.... next_inserted_row - value+9 - value+9 - value+9... next_inserted_row - value+5..' etc)

Is anyone able to help with that?

回答1:

As far as I can determine, this should give what you're asking for. The original matrix is M:

insertRange = [80 200];   %// number of lines to skip before inserting
chunkStart = 0;

while chunkStart < size(M,1)
   chunkEnd = chunkStart + randi(insertRange/4) * 4;
   %// add random value to column 4
   addedValue = randi(12);
   lastRow = min(chunkEnd,size(M,1));
   M(chunkStart+1:lastRow,4) = M(chunkStart+1:lastRow,4) + addedValue;
   if chunkEnd < size(M,1)
      %// we haven't reached the end; insert new row after chunkEnd
      newRow = M(chunkEnd,:);
      newRow(1) = newRow(1) + 6;
      newRow(3) = 2.0;
      newRow(4) = 69.0;
      newRow(6) = newRow(6) + 0.25;
      %// now adjust remaining rows (> chunkEnd)
      M(chunkEnd+1:end,1) = M(chunkEnd+1:end,1) + 11.0;
      M(chunkEnd+1:end,6) = M(chunkEnd+1:end,6) + 0.25;
      M = [M(1:chunkEnd,:); newRow; M(chunkEnd+1:end, :)];
      chunkEnd = chunkEnd+1;
   end
   chunkStart = chunkEnd;
end

Here's a sample run using a smaller data set and insertRange.

>> OriginalM(36:46,:)
ans =

     8.00000     1.00000     1.00000    56.00000   100.00000     8.75000     0.25000
     9.00000     1.00000     1.00000    68.00000   100.00000     9.00000     0.25000
     9.00000     1.00000     1.00000    76.00000   100.00000     9.25000     0.25000
     9.00000     1.00000     1.00000    72.00000   100.00000     9.50000     0.25000
     9.00000     1.00000     1.00000    48.00000   100.00000     9.75000     0.25000
    10.00000     1.00000     1.00000    67.00000   100.00000    10.00000     0.25000
    10.00000     1.00000     1.00000    71.00000   100.00000    10.25000     0.25000
    10.00000     1.00000     1.00000    66.00000   100.00000    10.50000     0.25000
    10.00000     1.00000     1.00000    47.00000   100.00000    10.75000     0.25000
    11.00000     1.00000     1.00000    60.00000   100.00000    11.00000     0.25000
    11.00000     1.00000     1.00000    72.00000   100.00000    11.25000     0.25000

and the output with the new row inserted after the 9 group:

>> M(36:46,:)
ans =

     8.00000     1.00000     1.00000    68.00000   100.00000     8.75000     0.25000
     9.00000     1.00000     1.00000    80.00000   100.00000     9.00000     0.25000
     9.00000     1.00000     1.00000    88.00000   100.00000     9.25000     0.25000
     9.00000     1.00000     1.00000    84.00000   100.00000     9.50000     0.25000
     9.00000     1.00000     1.00000    60.00000   100.00000     9.75000     0.25000
    15.00000     1.00000     2.00000    69.00000   100.00000    10.00000     0.25000
    21.00000     1.00000     1.00000    73.00000   100.00000    10.25000     0.25000
    21.00000     1.00000     1.00000    77.00000   100.00000    10.50000     0.25000
    21.00000     1.00000     1.00000    72.00000   100.00000    10.75000     0.25000
    21.00000     1.00000     1.00000    53.00000   100.00000    11.00000     0.25000
    22.00000     1.00000     1.00000    66.00000   100.00000    11.25000     0.25000


回答2:

These requirements aren't complete; for example, you never specify what you want in the 2nd, 5th, 6th, and 7th columns; for those I simply put NaNs. I also agree that the latter points are quite confusing - I don't know what you mean by "between" in a few instances. I have however put together what (I think you ask for) in a code, and in any case should give you the right ideas. The matrix m0 is the solution:

close all 
clear all
clc

%create q new rows in bunches of 4:
q = 20;

m0 =    [ 0    1.0000    1.0000   77.0000  100.0000         0    0.2500;...
     0    1.0000    1.0000   72.0000  100.0000    0.2500    0.2500;...
     0    1.0000    1.0000   69.0000  100.0000    0.5000    0.2500;...
     0    1.0000    1.0000   48.0000  100.0000    0.7500    0.2500;...
1.0000    1.0000    1.0000   65.0000  100.0000    1.0000    0.2500;...
1.0000    1.0000    1.0000   71.0000  100.0000    1.2500    0.2500;...
1.0000    1.0000    1.0000   62.0000  100.0000    1.5000    0.2500;...
1.0000    1.0000    1.0000   41.0000  100.0000    1.7500    0.2500;...
2.0000    1.0000    1.0000   62.0000  100.0000    2.0000    0.2500;...
2.0000    1.0000    1.0000   67.0000  100.0000    2.2500    0.2500;...
2.0000    1.0000    1.0000   71.0000  100.0000    2.5000    0.2500;...
2.0000    1.0000    1.0000   43.0000  100.0000    2.7500    0.2500;...
3.0000    1.0000    1.0000   71.0000  100.0000    3.0000    0.2500;...
3.0000    1.0000    1.0000   62.0000  100.0000    3.2500    0.2500;...
3.0000    1.0000    1.0000   67.0000  100.0000    3.5000    0.2500;...
3.0000    1.0000    1.0000   47.0000  100.0000    3.7500    0.2500;...
4.0000    1.0000    1.0000   69.0000  100.0000    4.0000    0.2500;...
4.0000    1.0000    1.0000   65.0000  100.0000    4.2500    0.2500;...
4.0000    1.0000    1.0000   60.0000  100.0000    4.5000    0.2500;...
4.0000    1.0000    1.0000   41.0000  100.0000    4.7500    0.2500;...
5.0000    1.0000    1.0000   74.0000  100.0000    5.0000    0.2500;...
5.0000    1.0000    1.0000   71.0000  100.0000    5.2500    0.2500;...
5.0000    1.0000    1.0000   65.0000  100.0000    5.5000    0.2500;...
5.0000    1.0000    1.0000   47.0000  100.0000    5.7500    0.2500];

L = length(m0);
%find random insert point:
insert_index = 4*(randi(L/4));
col1_val = m0(insert_index,1);

for j2 = 1:q
    added_random = randi(12);
    for j3 = 1:4
       index = (j2-1)*4 + j3;
       m_insert(index,:) = [ col1_val + 6, nan ,2 ,69 + added_random ,nan ,nan ,nan ];
    end 
    col1_val = col1_val + 1;

end

mfirst = m0(1:insert_index,:);
mlast = m0(insert_index+1:end,:);
m0 = [mfirst;m_insert;mlast];