save text file matlab - matlab

Another question on fprintf
I have a matrix s(n,5) that I want to shorten (just take columns 3,4 and 5) into s1(n,3) and save with a different name.
s1=s(:,3:5);
txtfilename = [Filename '-1.txt'];
% Open a file for writing
fid = fopen(txtfilename, 'w');
% print values in column order
% two values appear on each row of the file
fprintf(fid, '%f %f %f\n', s1);
fclose(fid);
I don't think I understood the way to use fprintf and rewrite my new matrix, because it is sorting the values.
Thanks for your help

The problem is that MATLAB stores data in column-major order, meaning that when you do s1(:), the first three values are the first three values in the first column not the first row. (This is how fprintf will read values out of s1.) For example:
>> M = magic(3)
M =
8 1 6
3 5 7
4 9 2
>> M(:)
ans =
8
3
4
1
5
9
6
7
2
You can simply transpose the matrix to output the way you want:
fprintf(fid, '%f %f %f\n', s1.');

Related

Matlab from text file to sparse matrix.

I have a huge text file in the following format:
1 2
1 3
1 10
1 11
1 20
1 376
1 665255
2 4
2 126
2 134
2 242
2 247
First column is the x coordinate while second column is the y coordinate.
It indicates that if I had to construct a Matrix
M = zeros(N, N);
M(1, 2) = 1;
M(1, 3) = 1;
.
.
M(2, 247) = 1;
This text file is huge and can't be brought to main memory at once. I must read it line by line. And save it in a sparse matrix.
So I need the following function:
function mat = generate( path )
fid = fopen(path);
tline = fgetl(fid);
% initialize an empty sparse matrix. (I know I assigned Mat(1, 1) = 1)
mat = sparse(1);
while ischar(tline)
tline = fgetl(fid);
if ischar(tline)
C = strsplit(tline);
end
mat(C{1}, C{2}) = 1;
end
fclose(fid);
end
But unfortunately besides the first row it just puts trash in my sparse mat.
Demo:
1 7
1 9
2 4
2 9
If I print the sparse mat I get:
(1,1) 1
(50,52) 1
(49,57) 1
(50,57) 1
Any suggestions ?
Fixing what you have...
Your problem is that C is a cell array of characters, not numbers. You need to convert the strings you read from the file into integer values. Instead of strsplit you can use functions like str2num and str2double. Since tline is a space-delimited character array of integers in this case, str2num is the easiest to use to compute C:
C = str2num(tline);
Then you just index C like an array instead of a cell array:
mat(C(1), C(2)) = 1;
Extra tidbit: If you were wondering how your demo code still worked even though C contained characters, it's because MATLAB has a tendency to automatically convert variables to the correct type for certain operations. In this case, the characters were converted to their double ASCII code equivalents: '1' became 49, '2' became 50, etc. Then it used these as indices into mat.
A simpler alternative...
You don't even have to bother with all that mess above, since you can replace your entire function with a much simpler approach using dlmread and sparse like so:
data = dlmread(filePath);
mat = sparse(data(:, 1), data(:, 2), 1);
clear data; % Save yourself some memory if you don't need it any more

How to write 2 matrices with different types of data to a single file in Matlab?

I have 2 matrices, with one having floating point numbers and the other, integer numbers. Both the matrices have the same number of rows but different number of columns.
I want to write both the matrices together to a file with each single line consisting of a single row from each matrix printed side-by-side.
How should I do this?
My try (unsuccessful) :
fid = fopen(nameF, 'w'); % Open for writing
fprintf('%d\n',fid);
for i=1:size(FloatMat,1)
fprintf(fid, '%f %d ', FloatMat(i,:),IntMat(i,:));
fprintf(fid, '\n');
end
fclose(fid);
Your problem is that the %f and %d of your fprintf only refers to the first and second columns. If there are more columns Matlab will repeat the pattern.
So you are saving the first column of FloatMat as float, the second column of FloatMat as Integer, etc...
You must specify the type of each column, but don't worry, you don't have to do it manually, use repmat instead
fprintf(fid, [repmat('%f ',1,size(FloatMat,2)) ' ' ...
repmat('%d ',1,size(IntMat,2)) '\n'], ...
FloatMat(i,:), IntMat(i,:));
PD: Note that I have separated the columns with space, as you did. Feel free to use \t or comma to separate them if needed.
PD: Also you can include the \n in the same line, so you can save one line of code.
This one actually writes both in float format with 8 digits precision, you will not get %d effect here but is only two lines:
BothMat = [FloatMat IntMat]
save(nameF, 'BothMat', '-ascii')
You don't need to complicate things using repmat int his case, just fprintf the float matrix first followed by the int matirx:
nRows = 5;
Mint = magic(nRows);
Mfloat = rand(nRows, 3);
fid = fopen('test.txt','w');
for row = 1:nRows
fprintf(fid,'%f\t', Mfloat(row,:));
fprintf(fid,'%d\t',Mint(row,1:end-1)); % only go to end to prevent trailing delimiter after final value of the row
fprintf(fid,'%d\n',Mint(row,end));
end
fclose(fid);
example output
0.392227 0.276923 0.317099 17 24 1 8 15
0.655478 0.046171 0.950222 23 5 7 14 16
0.171187 0.097132 0.034446 4 6 13 20 22
0.706046 0.823458 0.438744 10 12 19 21 3
0.031833 0.694829 0.381558 11 18 25 2 9

In matlab how can someone put the values from a single cell with multiple values within it seperated by a specific delimiter in a matrix?

I would like display the data from only one column of a .csv file in a matrix. There are multiple integer numbers (to be precise 3 numbers) separated by a semi-colon per cel for each row. Here is an example of how the data looks like:
A B
1;2;3
4;5;6
(note that A means column A, column B is empty)
The desired output would be an array in Matlab with 3 columns and 2 rows.
>> matrixFromCsvFile=
1 2 3
4 5 6
What I tried: was
fid = fopen('test.csv');
matrixFromCsvFile = textscan(fid, '%d %d %d', 'delimiter', ';')
fclose(fid);
Instead of the desired output I got this:
>> matrixFromCsvFile =
[2x1 int32] [2x1 int32] [2x1 int32]
>> matrixFromCsvFile{1}
>> ans =
1
4
Did I really just created 3 arrays within an array? I want just one. Luckily the 1 and 4 values are correct though. This already took me a long time to achieve, I'm stuck.
You can fix your example just by adding a CollectOutput flag to textscan:
M = textscan(fid, '%d %d %d', 'delimiter', ';','CollectOutput',1);
By default textscan outputs columns separately (so your data is there, just in e.g. M{1}, M{2}, M{3}). Setting CollectOutput puts consecutive columns of the same class into a single array.
e.g. this would give me five columns in five arrays:
M = textscan(fid, '%d %d %f %f %f');
This would give me two arrays, one containing the first two columns, one containing the last three:
M = textscan(fid, '%d %d %f %f %f','CollectOutput',1);
Use importdata:
M = importdata('test.csv',';',1)
matrixFromCsvFile = M.data
You could go on with
matrixFromCsvFile = cell2mat(matrixFromCsvFile);

Write Data from Matlab to a Text File

I need to save multiple arrays to a text file in the following format:
n=2 %number of arrays
r=3 %number of rows in the first array
1 2 3 % actual data
4 5 6
7 8 9
r=3 %number of rows in the second array
5 6 7 % actual data
1 2 3
7 8 9
Would you help please
Use fprintf. If your arrays are stored in a cell array so that you can iterate through them.
arrays = cell(N, 1); %A cell array of arrays
f = fopen('output.txt', 'w');
fprintf(f, 'n=%i\n', N);
for i=1:N
rows = size(arrays{i}, 1);
fprintf(f, '\nr=%i\n', rows);
for j=1:rows
fprintf(f, '%g ', arrays{i}(N, :));
fprintf(f, '\n');
end
end
fclose(f);
What have you done so far?
As a general rule, for this sort of thing your friends are the functions fprintf, which prints data to a file, and varargin, which allows you to supply a variable-length argument list to a function. A good signature for a function that handles this sort of task might therefore be
function [output_args] = pretty_save_to_file(fName, varargin)
Here fName is the name of the file you'd like your data saved to and varargin is a placeholder for the names of the matrices you'd like to save. Once you've filled in the gory details of the function, you should be able to call it using something like
pretty_save_to_file('output.txt', A, B, C) % prints matrices A, B, and C to output.txt
In addition, since you're looking to determine the number of rows in each matrix, you'll probably find the following snippet involving the size function useful:
[nrows, ncols] = size(A); % Stores the number of rows and columns of A in nrows, ncols
Finally, the fprintf function allows you to specify the desired formatting of your matrix.

Read 'm-to-n' row numbers from a txt file (MATLAB)

I'm trying to read data from a .txt file. The sample data is given below. I need an algorithm to read just M-N row numbers. While I can use while/for loops, I'm afraid that it might become very slow. Thanks!
a=[ 1 6 11 16 ;
2 7 12 17 ;
3 8 13 18 ;
4 9 14 19 ;
5 10 15 20] ; % data is in Test.txt -->
% fid = fopen('Test.txt');
% a=a.'; fprintf(fid, '%.3f\t%.3f\t%.3f\t%.3f\r\n', a(:)) ;
fid = fopen('Test.txt') ;
AnsMat = fscanf(fid, '%f %f %f %f')
AnsMat = [2 7 12 17 ; 3 8 13 18] ; % Read row-numbers 2 to 4 this time
You could try textscan which allows a HeaderLines parameter telling matlab how many lines to skip.
For example to read lines n (=2) to m(=4), you could do:
fid = fopen('Test.txt');
C = textscan(fid,'%f %f %f %f\n',m-n+1,'HeaderLines',n-1);
fclose(fid);
This does return the data as a cell array though so you have to convert it:
AnsMat = cell2mat(C);
If your data were in csv format instead of text format, you could use the command:
text=csvread('yourfile.csv',1,1,[1 1 m n])
Obviously, if your data is only available in text format, it would be just as much work to manually convert it as it would be to use the textscan option, but if your text file is being generated elsewhere where you would have control over the output format, this may streamline the process.