Convert an array of timestamps to seconds in Matlab - arrays

I'm new to SO and Matlab so please excuse any transgressions.
I'm trying to convert a seemingly simple array of timestamp strings to an equivalent array of seconds.
I wrote a this function:
% Function to calculate seconds from a timestamp in the following format:
% ddd hh:mm:ss.SSSS (example: 123 12:59:00.9999)
function a = TimestampToS(stamp)
% Uses the "named tokens" facility of MATLAB's "regexp" function.
expr = ['(?<ddd>\d+)' ... % ddd
' ' ... % Space " " separator
'(?<hh>\d+)' ... % hh
':' ... % Colon ":" separator
'(?<mm>\d+)' ... % mm
':' ... % Colon ":" separator
'(?<ss>\d+)' ... % ss
'.' ... % Dot "." separator
'(?<SSSS>\d+)']; % SSSS
parsedStamp = regexp(stamp, expr, 'names');
a = (str2double(parsedStamp.ddd) * 86400) + ...
(str2double(parsedStamp.hh) * 3600) + ...
(str2double(parsedStamp.mm) * 60) + ...
(str2double(parsedStamp.ss)) + ...
(str2double(parsedStamp.SSSS) * 0.0001);
It works great for an individual string:
>> TimestamptoS('123 12:59:00.9999')
ans =
1.067394099990000e+007
But if I try to use a cell array I get:
Attempt to reference field of non-structure array.
How can I get an array of seconds? I have tried all kinds of conversions of the input data and "parsedStamp" but nothing works. I don't understand Matlab or its matrix notation well enough. Any help gratefully received!
PS This is not a regexp question, no replies about regexp please!

You can do it very easily without modifying your function, by using cellfun. This essentially extracts each cell of the cell array and passes it to your function.
>> cellArray = {'123 12:59:00.9999','130 12:59:00.9999'}; % for example
>> cellfun(#TimestampToS,cellArray)
ans =
1.0e+007 *
1.067394099990000 1.127874099990000

Related

SSIS For Loop - Increment 'YYYYMM' by Month in Loop

I am trying to execute a for loop that passes a begin date in the format like '201812' and goes up increments to an end date (as an example) of '201903'. The variables get passed as Integers to stored procs which then grab and insert data based on those values. I was trying to implement the pattern found here but it does not seem to be correctly incrementing:
SSIS For Loop Container with Date Variable
I have set up variables as follows:
The ETLBeginPeriod and ETLEndPeriod are set in Execute SQL Tasks here:
And then here are the expressions in the For Loop
The full expression in the AssignExpression is
#[User::Counter] = LEFT((DT_WSTR,19)(DATEADD("mm",1,(DT_DBDATE)(LEFT((DT_WSTR, 10) (#[User::Counter]),4) + "-" + RIGHT((DT_WSTR, 10) (#[User::Counter]),2) + "-" + "01"))),4) + SUBSTRING((DT_WSTR,19)(DATEADD("mm",1,(DT_DBDATE)(LEFT((DT_WSTR, 10) (#[User::Counter]),4) + "-" + RIGHT((DT_WSTR, 10) (#[User::Counter]),2) + "-" + "01"))),6,2)
When testing the AssignExpression the expression itself does return a correct value (i.e. it will change 201808 to 201809 but this doesn't seem to be getting hit. It will get the correct value on the initial pass and run 201808 and then try again with 201808. So it doesn't seem to change the Counter Value.
I think the main issue is that you forgot to cast the whole result as integer. Try using the following expression:
#[User::Counter] = (DT_I4)(LEFT((DT_WSTR,19)(DATEADD("mm",1,(DT_DBDATE)(LEFT((DT_WSTR, 10) (#[User::Counter]),4) + "-" + RIGHT((DT_WSTR, 10) (#[User::Counter]),2) + "-" + "01"))),4) + SUBSTRING((DT_WSTR,19)(DATEADD("mm",1,(DT_DBDATE)(LEFT((DT_WSTR, 10) (#[User::Counter]),4) + "-" + RIGHT((DT_WSTR, 10) (#[User::Counter]),2) + "-" + "01"))),6,2))
I figured this out - I decided to add a script task to view the variables and it turns out that they were incrementing correctly, but I had the wrong variable assigned to get passed to the stored procedure. I had originally been using the ETLBeginPeriod and forgot to change it to the Counter variable. Once I did that it worked. Arg.

Iterating in dataframe and insert on text

There is a DataFrame loaded in pandas with size m*n, m can be big compare with columnes n which are values from 2 to 20.
each value from m*n has to be add to expecific text, it means that text between any value is constant.
I tried with For and If nested sentences, no good result how to make step from df.iloc[0,0] to df.iloc[m,n] and insert in text.
textA + df.iloc[0,0] + textB + df.iloc[0,1] + .... + textX + df.iloc[0,n]
textA + df.iloc[1,0] + textB + df.iloc[1,1] + .... + textX + df.iloc[1,n]
.
.
.
textA + df.iloc[m,0] + textB + df.iloc[m,1] + .... + textX + df.iloc[m,n]
I have 2 files, one include textA textB ... textX Second file is csv type where pandas dataframe is generated.
With dataframe and text prepare array above.
thanks for any tip.
Not exactly clear on your requirement but takae a look if the following code is able to help you iterate between df.iloc[0,0] to df.iloc[m,n] while adding information from your text file (in this case a text variable)
# i am using a dummy variable for the text data as i am not sure how your data look like
text = ['textA', 'textB', 'textC']
new_text = []
# using a nested for loop to iterate
for row in range(len(df)):
for col in range(len(df.columns)):
new_text.append(text[col] + str(df.iloc[row, col]))

Convert Cell to an Array

i have a cell array with dimensions 1x16384 consists of 16384 numbers.
I tried using cell2mat(), but i get one element with all those numbers in it.
How do i convert it to an array with 1x16384 dimension.
Assuming B= cell2mat(A);
A looks like;
Columns 16382 through 16384
'15.849' '16.337' '14.872'
where as B looks like;
B =
-8.921-8.433-2.5745.23911.58714.02811.5876.7041.821-1.109-2.085-1.5970.3562.
console ;
class(A), class(A{1}), size(A), size(A{1})
ans =
cell
ans =
char
ans =
1 16384
ans =
1 6
For mcve,
Csv input file
DELIMITER = ' ';
HEADERLINES = 3;
% Import the file
newData1 = importdata('C:\Python34\co2a0000364.csv', DELIMITER, HEADERLINES);
% Create new variables in the base workspace from those fields.
vars = fieldnames(newData1);
for i = 1:length(vars)
assignin('base', vars{i}, newData1.(vars{i}));
end
new = textdata(6:16452,4);
A = new;
for z = 1:63
A(i*257)=[];
end
B = A'
A= B;
A= cell2mat(B)
B= A
You way of importing data is quite clumsy. I invite you to read the textscan function documentation, which allows much more flexibility in importing mixed data type (text and numeric data).
I propose you another way of importing, which uses textscan:
%% // Import only the 4th column of data
fid = fopen('co2a0000364.csv') ;
M = textscan( fid , '%*s%*s%*s%f' , 'Delimiter',' ' , 'HeaderLines',4) ;
fclose(fid) ;
M = cell2mat(M) ;
%% // reshape to have each channel in its own colum
M = reshape( M , 257 , [] ) ;
%% // Delete the channel number from the data table
M(1,:) = [] ;
This will give you a nice 256*64 matrix, containing the data for each of the 64 channels in one column.
if you really want them all in sequence in one column, just add:
M = M(:) ;
to the end of the code.
Explanation note: the textscan format specifier I use: '%*s%*s%*s%f' tells the function to read 4 elements per line:
- 3x strings : %s
- 1x floating point number: %f
adding the character * in the format specifier (for example %*s) for an element tells the function to ignore the element, so it does not put it into the output.

Problems with Expressions in C

I have two functions written that have simple assignment statements with very simple expressions. The expressions are the same for both functions, however, they involve different variable types: One function uses an array of structs, the other just uses a typedef'd struct.
When running the functions, the second function fails to divide by 256, and I get very high values that are not "normalized". I have to uncomment the second line in the second function (valueB = valueB / 256) to get it to work.
The first function, however, works perfectly.
Heres the statement in Function One:
value = ((p[0].value * p2Area)+(p[1].value * p3Area)+(p[2].value * p0Area)+(p[3].value * p1Area) / 256);
Heres the statement in Function Two:
valueB = ((dataPoints.p0B * p2Area)+(dataPoints.p1B * p3Area)+(dataPoints.p2B * p0Area)+(dataPoints.p3B * p1Area) / 256);
//valueB = valueB / 256;
Why would this happen?
Also, I pass the functions the same numbers and it doesn't seem to help.
This is on MacOSX 10.6.8, inside Xcode 3.2.6
Are you absolutely sure the first one works properly? You have
value = ((p[0].value * p2Area)+(p[1].value * p3Area)+(p[2].value * p0Area)+(p[3].value * p1Area) / 256);
I think you want:
value = (((p[0].value * p2Area)+(p[1].value * p3Area)+(p[2].value * p0Area)+(p[3].value * p1Area)) / 256);
Similar thing with the second. I think it should be:
value = (((p[0].value * p2Area)+(p[1].value * p3Area)+(p[2].value * p0Area)+(p[3].value * p1Area)) / 256);
In both cases I think you want to divide the sum of the products by 256. Not just the last one. My change only involves placing an extra set of parentheses around the sum of the product subexpressions and dividing the entire thing by 256
In all languages there is an order by which mathematical (and all other operators are completed). It just so happens that * and / are higher in precedence than + and - in C/C++ You may refer to this link for more details.
To simplify what happened to you, I will create this simple equation:
2 + 4 + 6 + 4 / 2
Since division occurs first (and there are no parentheses to alter the order) it gets computed as:
2 + 4 + 6 + (4 / 2) = 14
Not:
(2 + 4 + 6 + 4) / 2 = 8
So my change to your code was the same as putting parentheses around 2 + 4 + 6 + 4 / 2 giving (2 + 4 + 6 + 4) / 2 and forcing the division to be done last after all the additions are completed.

Need some help parsing a string in C

Using fgets, I have read in a line from a text file. The line may be something like this:
# O^6+ + H -> O^5+ + H^+
Or it may be this:
# Mg^12+ + H -> Mg^11+ + H^+
or this:
# Ne^10+ + He -> Ne^9+ + He^+
Or a multitude of other possibilities.
I am trying to extract the ion, the charge and the atom terms from the string.
I tried something like this:
sscanf(line,"# %2s^%d+ + %2s",cs->ION,&(cs->Z),cs->ATOM);
I also tried this:
sscanf(line,"# %[^^]s^%d+ + %2s",cs->ION,&(cs->Z),cs->ATOM); Because I was picking up the '^' character.
I just can't seem to get this to work for every case. Any suggestions are appreciated.
Your try with the format string
"# %[^^]s^%d+ + %2s"
was almost right, except that after the %[^^] there has to be no s, i. e.
"# %[^^]^%d+ + %2s"
works.

Resources