Insert rows into Excel with MATLAB - excel

The data in my Excel files is supposed to be contentious (index in the first column). But some data is missing in the file. For example, # 5, and 6 are missing between $ 4 and 7. My purpose are (1) identify the file with missing data and (2) if data is missing insert rows to make it continuous. Can anyone tell me how to add in rows in the existing data? Using xlswrite I can only add in rows at the end of the file or replace some rows.
EDIT 1:
I have another set of file in which the index is not so direct. The first 3 columns are described below (as shown in the Excel file):
Column 1:Year: 2003 (read as number in matlab)
Column 2:Date: 1-Sep (read as text in matlab)
Column 3:Time: 1:00 (1:00 read as number 0.04167 and 2:00 read as 0.0833, not sure how it works)
Then the way to tell if it is continuous will be quite complicate since there will be different years, months, and days. Could you give some hint on this?

Basically you need to read the entire data, preferably in raw(cell) format, add the missing rows(with respect to the indices) and write back.
Based on your question, this code might work -
% NOTE: We are assuming that the indexing starts with 1
% Read data from input excel file with missing indices
[num,txt,raw] = xlsread('input.xls');
% Error-checking
if (size(num,1)-num(end,1)~=0)
disp('At least one index is missing!');
end
% Expand data such that all indices are covered.
data1=NaN(num(end,1),size(raw,2));
data1(:,1) = 1:num(end,1);
data1=num2cell(data1);
k1=1;
for k = 1:num(end,1)
if(num(k1,1)==k)
data1(k,:)= raw(k1,:);
k1 = k1+1;
end
end
% Write data
xlswrite('output.xls',data1);
EDIT 1:
In view of your new requirements, additional code is added next.
Please note few things about this code -
The code adds data for every year and not from a specific month, date and time to another specific month, date and time. If you wish to achieve that, please edit the associated
function - 'create_comp_sheet'.
It saves an intermediate file named - 'proper_base_data.xls', which maybe deleted at the end of the code.
%% MAIN CODE - CODE1.M
INPUT_FILENAME = 'input.xls'; % Excel file that has some missing year,date and time info
OUTPUT_FILENAME = 'output.xls'; % Excel file that has data from the input file along with all the missing year,date and time info
%% Base data
start_year=2003;
end_year=2005;
proper_base_data = create_comp_sheet(start_year,end_year);
xlswrite('proper_base_data.xls',proper_base_data);
[num,txt,raw] = xlsread('proper_base_data.xls');
base_data=cell(size(num,1),1);
for row_ID = 1:size(num,1)
base_data(row_ID) = {strcat(num2str(cell2mat(raw(row_ID,1))),'-', cell2mat(raw(row_ID,2)),'-',num2str(round(24*cell2mat(raw(row_ID,3)))))};
end
%% Input data
[num,txt,raw] = xlsread(INPUT_FILENAME);
input_data=cell(size(num,1),1);
for row_ID = 1:size(num,1)
input_data(row_ID) = {strcat(num2str(cell2mat(raw(row_ID,1))),'-', cell2mat(raw(row_ID,2)),'-',num2str(round(24*cell2mat(raw(row_ID,3)))))};
end
%% Setup final data
final_data = num2cell(NaN(size(proper_base_data,1),size(raw,2)));
final_data(:,1:3) = proper_base_data;
for k1=1:size(input_data,1)
for k2=1:size(base_data,1)
if strcmp(cell2mat(base_data(k2)),cell2mat(input_data(k1)))
final_data(k2,4:end) = raw(k1,4:end);
end
end
end
%% Write final data to excel
xlswrite(OUTPUT_FILENAME,final_data);
Associated function -
function data1 = create_comp_sheet(start_year,end_year)
months_string = {'Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'};
date_count = [31 28 31 30 31 30 31 31 30 31 30 31];
num_hours = 24;
data1=[];
for year_ID = start_year:end_year
for month_ID = 1:numel(months_string)
days_per_month = date_count(month_ID);
if rem(year_ID,4)==0 && month_ID ==2
days_per_month = days_per_month+1;
end
for date_ID = 1:days_per_month
year = repmat({num2str(year_ID)},[num_hours 1]);
date = repmat({strcat(num2str(date_ID),'-',char(months_string(month_ID)))},[num_hours 1]);
time=cell(num_hours,1);
for k = 1:num_hours
time(k) = {strcat(num2str(k),':00')};
end
data1 = [data1 ; [year date time]];
end
end
end
return;
Hope this saves all your troubles!

Related

Number of samples, -5, must be non-negative using panda python

I have a csv file with date and time. I want to give specific timeinterval (60min) in between time range (start time and end time). I wrote a code with a date. But it gives me an error Number of samples, -5, must be non-negative. Then I checked with separate csv file with less data. Then I found that I have time like 9:53 , 10:20 ,11:42 .... Then when I'm dividing to find num_periods then its give me an error.
example
take date range like
2018 /8/6 start time is 6:00
2018/8/6 end time is 23:52
then it between I have time like 7:00, 8:52,10:42 so on.
after that in next day I have a time period like this.
So when I tried to find a num_periods then it give me this error.
I want to specify time in between this time_range
(start_time+time_interval(3600 in seconds (60min)) in between time_range)
Can anyone give me solution for this?
my code is,
time_interval = 3600
date_array = []
date_array.append(pd.to_datetime(data['date'][0]).date())
start_time = []
end_time = []
temp_date = pd.to_datetime(data['date'][0]).date()
start_time.append(pd.to_datetime(data['time'][0], format='%H:%M:%S').time())
for i in range(len(data['date'])):
cur_date = pd.to_datetime(data['date'][i]).date()
if( cur_date > temp_date):
end_time.append(pd.to_datetime(data['time'][i-1], format='%H:%M:%S').time())
start_time.append(pd.to_datetime(data['time'][i], format='%H:%M:%S').time())
date_array.append(cur_date)
temp_date = cur_date
end_time.append(pd.to_datetime(data['time'][len(data['date'])-1], format='%H:%M:%S').time())
datetime_array = []
for i in range(len(date_array)):
s_time = datetime.datetime.combine(date_array[i],start_time[i])
e_time = datetime.datetime.combine(date_array[i], end_time[i])
timediff = (e_time - s_time)
num_periods = int(timediff.total_seconds()/time_interval) +1
time_list = pd.date_range(start=s_time, end = e_time, periods=num_periods ).to_pydatetime()
datetime_array.extend(time_list)
error:
subset of my csv file
It looks like num_periods is negative:
num_periods = int(timediff.total_seconds()/time_interval) + 1
the easiest solution is to take the abs value instead:
num_periods = abs(int(timediff.total_seconds()/time_interval)) + 1
Note: that date_range supports ranges in reverse order (where start > end).

How to save data in excel file MATLAB?

I want to save pitch,yaw and roll data in excel file for all frames. Eg: if i have 200 frames then i want to save 200 frames information in excel file. I have tried but my code only stores one frame data.exceldata
fitting_model='models/Chehra_f1.0.mat';
load(fitting_model);
mov=VideoReader('7_a.avi'); %Read video file and create an object
c=mov.NumberOfFrames;
for k=1:c
a = read(mov, k);
img=im2double(a);
disp(['Detecting Face in ']);
faceDetector = vision.CascadeObjectDetector(); % detect face in an image
bbox = step(faceDetector, img); %create boundary box around face
test_init_shape = InitShape(bbox,refShape); %initialize facial points in variable
test_init_shape = reshape(test_init_shape,49,2);
if size(img,3) == 3
test_input_image = im2double(rgb2gray(img));
else
test_input_image = im2double((img));
end
disp(['Fitting']);
MaxIter=6;
test_points = Fitting(test_input_image,test_init_shape,RegMat,MaxIter);
load('3D_Shape_Model.mat');
n=49;
test_image=img;
imshow(test_image);hold on;
% % Compute 3D Head Pose
if(n==49)
test_shape=test_points;
[pitch,yaw,roll] = ComputePose(PDM_49,test_shape(:));
filename='framesdata.xlsx';
header = {'Pitch', 'yaw ','roll'};
new_data = num2cell([pitch(:), yaw(:), roll(:)]);
output = [header; new_data];
xlswrite(filename,output);
end
plot(test_shape(:,1),test_shape(:,2),'b*');
title([num2str(i),' : Pitch = ',num2str(pitch),' ; Yaw = ',num2str(yaw),' ; Roll = ',num2str(roll)]);
set(gcf,'units','normalized','outerposition',[0 0 1 1]);
pause(0.5);
close all;
end
As #excaza stated, you will need to move the xlswrite command out of your loop or specify the cells you are writing. Please see the xlswrite Doc for more information. The correct syntax would be :
xlswrite(filename,A,xlRange)
The following is the example they provide:
filename = 'testdata.xlsx';
A = {'Time','Temperature'; 12,98; 13,99; 14,97};
sheet = 2;
xlRange = 'E1';
xlswrite(filename,A,sheet,xlRange)
You will just need to provide xlswrite the address to start writing data.

How to find data between two values

I am trying to find the data between two values. I am using this code in a GUI programme, the starting_value and ending_value which you can see in the code below are selected from 2 listboxes in a previous part of the code.
% --- Executes on button press in CalculateIntensity.
function CalculateIntensity_Callback(hObject, eventdata, handles)
% hObject handle to CalculateIntensity (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Trapz function
starting_value = getappdata(0,'StartValue');
ending_value = getappdata(0,'EndValue');
StartingValue = str2mat(starting_value)
EndingValue = str2mat(ending_value)
A = getappdata(0,'XYarray')
data_found = A(A(:,[1,2]) > StartingValue & A(:,[1,2]) < EndingValue)
I found help on:
http://www.mathworks.com/matlabcentral/answers/8556-how-to-find-vector-elements-between-two-values-efficiently
However the
data_found = A(A(:,[1,2]) > StartingValue & A(:,[1,2]) < EndingValue)
part of the code wont work for me, I think starting_value and ending_value are strings so I tried converting it to a matrix but I get the error:
Error using <
Matrix dimensions must agree.
Error in MichelleLaycockGUImainwindow>CalculateIntensity_Callback (line 119)
data_found = A(A(:,[1,2]) > StartingValue & A(:,[1,2]) < EndingValue)
an example of data used is:
A =
1.0e+03 *
0.1660 1.1570
0.1664 0.4650
0.1668 0
0.1672 1.0200
0.1676 1.0110
0.1680 1.0200
0.1684 1.0640
0.1688 1.1100
0.1692 1.0370
0.1696 1.0050
0.1700 1.0750
0.1704 1.0850
0.1708 1.1310
0.1712 1.0630
0.1716 1.0370
0.1719 1.1070
0.1724 1.1450
I'm not really sure where I'm going wrong, any help would be greatly appreciated as it's all I need to complete my work. Thanks in advance!
As some of the values in my data vary rather than just decreasing or increasing the greater than or equal to method I was originally trying to use did not work. So rather than using the loop to get the data between the two points selected I went with a different method.
I use[~,indx1]=ismember(StartingValue,A,'rows') this finds the row number of the selected data and then I use this information to extract the data between and including the selected data.
Here is the full code I used to do this:
starting_value = getappdata(0,'StartValue');
ending_value = getappdata(0,'EndValue');
StartingValue = str2num(starting_value);
EndingValue = str2num(ending_value);
A = getappdata(0,'XYarray');
[~,indx1]=ismember(StartingValue,A,'rows');
[~,indx2]=ismember(EndingValue,A,'rows');
arrayfortrapz = A(indx1:indx2,1:2); %array of data including and between selected data
I hope this of some help to anybody that may run into a similar issue.

Xlsx or csv retrieve in Matlab

I have points data in .xlsx and I want to read and store them in p array in Matlab. These points are only 3D co-ordinates of x,y,z such that having understood three columns and not prdfined rows. How I can retrieve them from .xlsx or .csv if I need fast retrieval as I tried to retrieve .xlsx and its response time is slow and returns an empty array. Possibly store them in transposed form and transpose it back.
My Code: .Xls read
A = xlsread('data.xlsx')
Output:
A =
[]
My Code: .CSV read
M = csvread('data.csv')
Output:
Error using dlmread (line 139)
Mismatch between file and format string.
Trouble reading number from file (row 2u, field 1u) ==> ;\n
Error in csvread (line 48)
m=dlmread(filename, ',', r, c);
Points Set 1:
-191.2442 187.7193 1.0000;
-155.2995 152.6316 2.0000;
-182.0276 104.6784 3.0000;
-148.8479 84.7953 4.0000;
Points Set 2:
-142.3963 83.6257 5.0000;
-102.7650 133.9181 6.0000;
-56.6820 164.3275 7.0000;
-30.8756 124.5614 8.0000;
-23.5023 118.7135 7.0000;
-9.6774 110.5263 6.0000;
26.2673 90.6433 5.0000;
-42.8571 -6.4327 4.0000;
10.5991 7.6023 3.0000;
Points Set 3:
-73.2719 84.7953 9.0000;
-137.7880 15.7895 10.0000;
-92.6267 -30.9942 9.0000;
-42.8571 19.2982 8.0000;
41.0138 -15.7895 4.0000;
71.4286 -41.5205 6.0000;
90.7834 -14.6199 5.0000;
See if this slightly twisted one using importdata works for you -
C1 = importdata(file1) %%// file1 is your CSV filename
t1 = regexp(C1,'\s','Split')
t2 = horzcat(t1{:})
t2 = strrep(t2,';','')
M = cellfun(#str2num,reshape(t2(~strcmp(t2,'')),3,[])')
Edit 1: This case assumes you have a CSV file that has all the Point Sets clustered together but one by one (without spaces between the Point Sets and their data and also between the end of a Point Set and the declaration of the arrival of the next Point Set).
So, the input CSV file would look like this for the given data in the question -
Points Set 1:
-191.2442 187.7193 1.0000;
-155.2995 152.6316 2.0000;
-182.0276 104.6784 3.0000;
-148.8479 84.7953 4.0000;
Points Set 2:
-142.3963 83.6257 5.0000;
-102.7650 133.9181 6.0000;
-56.6820 164.3275 7.0000;
-30.8756 124.5614 8.0000;
-23.5023 118.7135 7.0000;
-9.6774 110.5263 6.0000;
26.2673 90.6433 5.0000;
-42.8571 -6.4327 4.0000;
10.5991 7.6023 3.0000;
Points Set 3:
-73.2719 84.7953 9.0000;
-137.7880 15.7895 10.0000;
-92.6267 -30.9942 9.0000;
-42.8571 19.2982 8.0000;
41.0138 -15.7895 4.0000;
71.4286 -41.5205 6.0000;
90.7834 -14.6199 5.0000;
Please note that the result from the codes would be a struct of arrays.
Code
C1 = importdata(file1) %%// file1 is your CSV filename
ind1 = cellfun(#isempty,strfind(C1,'Points'))
start_ind = find(~ind1)+1
s1 = find(~ind1)-1;
stop_ind = [s1(2:end) ; numel(ind1)]
for k = 1:numel(start_ind)
data1 = C1(start_ind(k):stop_ind(k))
t1 = regexp(data1,'\s','Split')
t2 = strrep(horzcat(t1{:}),';','')
t2 = t2(~strcmp(t2,''))
array(k).data = cellfun(#str2num,reshape(t2,3,[])'); %%//'
end
You are using the row separator ;\n (semicolon + new line). I don't know any function understand this format. Using texstscan is probably the best option:
fid=fopen(...)
M=cell2mat(textscan(line,'%f,%f,%f;\n'));
fclose(fid);

Writing data to excel files, MATLAB

I am using MatlabR2011a on my Windows 7 machine.
I have a folder of 635 text files. Each file contains multiple rows and 2 columns. I am trying to loop through the folder and read each file and write these values to excel. So far this is what I have:
close all; clc;
dirname = uigetdir;
Files = dir(fullfile(dirname,'*.txt'))
for k = 1:635
j =1
filename = fullfile(dirname,Files(k).name);
fid = fopen(filename);
x = fgetl(fid)
while ischar(x)
x = fgetl(fid)
a2 = strtrim(x);
a3 = textscan(a2,'%s');
a4 = a3{1}{1};
a5= a3{1}{2};
pos3 = strcat('A',num2str(j));
xlswrite('sample_output',{a4,a5},'Sheet1',pos3)
j = j+1;
end
fclose(fid);
end
It keeps giving me the following error after finishing reading the first file.
Error using ==> strtrim Input should be a string or a cell array of strings.
A sample input file looks like this:
15076 4636259
15707 4636299
15714 1781552
15721 4204950
15730 2174919
16209 4636510
16413 4758572
16470 4445808
17519 311397
17667 2116489
17739 1729694
18024 3210756
18627 3714194
18695 4192858
19141 632766
19318 1923574
19438 1255216
19493 4635020
19771 4770250
How can I fix this? Would appreciate help with this!
In the while loop, cut the line
x=fgetl(fid)
...and paste it before the end statement right after j=j+1.
The error occurs because you get a line before the while statement, then you use the while statement to test validity of the string (all fine so far), but then immediately get the subsequent line before you perform your string operation. The call to fgetl at the start of the while block could return an EOF, causing subsequent string manipulation functions to fail.
Also... The code would be more robust if you set your for loop like so
for k=1:numel(Files)
Since all your data are numeric this should work. Give it a try.
dirname = uigetdir;
Files = dir(fullfile(dirname,'*.txt'))
j =0;
for k = 1:numel(Files)
filename = fullfile(dirname,Files(k).name);
x = dlmread(filename,'\t'); %# I assume tab-delimiter
j = j + size(x, 1);
xlswrite( 'sample_output', x, 'Sheet1',sprintf('A%d',j) )
end

Resources