Extracting number after a string in header of CSV file

6 visualizaciones (últimos 30 días)
Jason
Jason el 7 de Feb. de 2025
Editada: Walter Roberson el 7 de Feb. de 2025
Hello, I have a CSV file that contains information in the headers and then numerical data.
I have no problem loading the numerical tabulated data into a uitable via readtable, but I want to pick out several strings within the header too.
I particularly want to extract the numbers in these lines
1: Memory Length,1000000,
2: Horizontal Scale,2.000E-04,
3: Sampling Period,2.000E-09,
Im nearly there but just can't quite get it:
fullpath=fullfile(folder,file)
l=readlines(fullpath);
Key = 'Memory Length';
line_idx=find(startsWith(l,Key))
Str=l(line_idx)
class(Str)
Index = strfind(Str, Key)
Str(Index(1) + length(Key):end)
line_idx =
2
Str =
"Memory Length,1000000,"
ans =
'string'
Index =
1
ans =
1×0 empty string array
Here is the typical file (also attached)
Format,1.0B,
Memory Length,1000000,
IntpDistance,0,
Trigger Address,-1,
Trigger Level,2.200E+00,
Source,CH1,
Vertical Units,V,
Horizontal Units,S,
Horizontal Scale,2.000E-04,
Sampling Period,2.000E-09,
Horizontal Old Scale,2.000E-04,
Horizontal Old Position,1.000E-03,
Firmware,V1.27.001,
Mode,Detail,
Waveform Data,
6.891787e-11,5.00e+00,
2.068918e-09,5.00e+00,
4.068918e-09,4.76e+00,
6.068918e-09,4.24e+00,
8.068918e-09,4.24e+00,
  1 comentario
Jason
Jason el 7 de Feb. de 2025
Editada: Walter Roberson el 7 de Feb. de 2025
Oooh, just seen using readlines gives a string array. So can use this:
pat = digitsPattern
newStr = extract(Str,pat)
But it falls over with the E here "Horizontal Scale,2.000E-04"
l=readlines(fullpath);
Key = 'Memory Length';
line_idx=find(startsWith(l,Key))
Str=l(line_idx)
pat = digitsPattern
MemoryLength = str2double(extract(Str,pat))
Mem_Million=MemoryLength/(10^6)
Key='Horizontal Scale';
line_idx=find(startsWith(l,Key))
Str=l(line_idx)
pat = digitsPattern
H_Scale = str2double(extract(Str,pat))
Str =
"Horizontal Scale,2.000E-04,"
pat =
pattern
Matching:
digitsPattern
H_Scale =
2
0
4

Iniciar sesión para comentar.

Respuesta aceptada

Star Strider
Star Strider el 7 de Feb. de 2025
One approach —
C1 = readcell('DummyData.txt')
C1 = 43x2 cell array
{'Format' } {'1.0B' } {'Memory Length' } {[ 1000000]} {'IntpDistance' } {[ 0]} {'Trigger Address' } {[ -1]} {'Trigger Level' } {[ 2.2000]} {'Source' } {'CH1' } {'Vertical Units' } {'V' } {'Vertical Units Div' } {[ 0]} {'Vertical Units Extend Div'} {[ 16]} {'Label' } {[<missing> ]} {'Probe Type' } {[ 0]} {'Probe Ratio' } {[ 10]} {'Vertical Scale' } {[ 1]} {'Vertical Position' } {[ -1.7600]} {'Horizontal Units' } {'S' } {'Horizontal Scale' } {[2.0000e-04]}
str = {'Memory Length','Horizontal Scale','Sampling Period'}';
idx = cellfun(@(x)strcmp(C1(:,1), x), str, 'Unif',0);
for k = 1:numel(idx)
val(k,:) = C1{idx{k},2};
end
Results = table(str, val)
Results = 3x2 table
str val ____________________ ______ {'Memory Length' } 1e+06 {'Horizontal Scale'} 0.0002 {'Sampling Period' } 2e-09
.
  4 comentarios
Jason
Jason el 7 de Feb. de 2025
Editada: Walter Roberson el 7 de Feb. de 2025
Is there a reason why the "table" isn't showing up in the command window?
fullpath=fullfile(folder,file)
opts = detectImportOptions(fullpath);
opts.DataLines=[1,100]; % limit the read to just the headers as 1M lines
C1 = readcell(fullpath,opts);
str = {'Memory Length','Horizontal Scale','Sampling Period'}'
idx = cellfun(@(x)strcmp(C1(:,1), x), str, 'Unif',0);
for k = 1:numel(idx)
val(k,:) = C1{idx{k},2}
end
Results = table(str, val)
fullpath =
'F:\IMAGES\ATS_IMAGES\2025\ScopeReadings\DS0030.CSV'
str =
3×1 cell array
{'Memory Length' }
{'Horizontal Scale'}
{'Sampling Period' }
val =
1000000
val =
1.0e+06 *
1.0000
0.0000
val =
1.0e+06 *
1.0000
0.0000
0.0000
Star Strider
Star Strider el 7 de Feb. de 2025
It should.
It does when I run it on my computer offline (R2024b):
Results =
3×2 table
str val
____________________ ______
{'Memory Length' } 1e+06
{'Horizontal Scale'} 0.0002
{'Sampling Period' } 2e-09
I copied that from my Command Window, and pasted it here. This should also work in R2023b, although I can’t specifically test it.
If all else fails, perhaps writetable and type would work.
.

Iniciar sesión para comentar.

Más respuestas (1)

Cris LaPierre
Cris LaPierre el 7 de Feb. de 2025
There are lots of ways to do this. Here is one modified from code I shared here: https://www.mathworks.com/matlabcentral/answers/2172834-2d-matrix-resize-or-interpolation#comment_3323358
data = readData('DummyData.txt')
data = struct with fields:
Format: '1.0B' MemoryLength: 1000000 IntpDistance: 0 TriggerAddress: -1 TriggerLevel: 2.2000 Source: 'CH1' VerticalUnits: 'V' VerticalUnitsDiv: 0 VerticalUnitsExtendDiv: 16 Label: ' ' ProbeType: 0 ProbeRatio: 10 VerticalScale: 1 VerticalPosition: -1.7600 HorizontalUnits: 'S' HorizontalScale: 2.0000e-04 HorizontalPosition: 1.0000e-03 HorizontalMode: 'Main' SincETMode: 'Real Time' SamplingPeriod: 2.0000e-09 HorizontalOldScale: 2.0000e-04 HorizontalOldPosition: 1.0000e-03 Firmware: 'V1.27.001' Mode: 'Detail' Waveform: [18x2 double]
plot(data.Waveform(:,1),data.Waveform(:,2))
xlabel("Time - "+data.HorizontalUnits)
ylabel("Amplitude - "+data.VerticalUnits)
function data = readData(fname)
r=0;
data = struct;
fid = fopen(fname);
while ~feof(fid)
ln = fgetl(fid);
[param,val] = strtok(ln,",");
switch param
case 'Waveform Data'
fseek(fid,0,'eof');
fgetl(fid);
otherwise
val = strtok(val,',');
pat = asManyOfPattern(characterListPattern("0123456789-+.E"));
nums = extract(val,pat);
Param = matlab.lang.makeValidName(param);
if length(val)==length(nums{1})
data.(Param) = str2double(val);
else
data.(Param) = val;
end
end
r = r+1;
end
fclose(fid);
val = readmatrix(fname,'FileType','text','NumHeaderLines',r);
data.Waveform = val;
end
  3 comentarios
Jason
Jason el 7 de Feb. de 2025
Could you expand on this line please
Param = matlab.lang.makeValidName(param);
Cris LaPierre
Cris LaPierre el 7 de Feb. de 2025
Editada: Cris LaPierre el 7 de Feb. de 2025
As an example, 'Vertical Units' cannot be used as a fieldname since it is not a valid variable name. This command converts it into a valid variable name so that the parameter name can be used as the field name in the returned structure.
matlab.lang.makeValidName('Vertical Units')
ans = 'VerticalUnits'

Iniciar sesión para comentar.

Categorías

Más información sobre Characters and Strings en Help Center y File Exchange.

Productos


Versión

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by