Elements of table equal to elements of another table

조회 수: 4 (최근 30일)
Daphne PARLIARI 2020년 1월 24일
댓글: Guillaume 2020년 1월 27일
Hi all!
I have a list of stations (see .txt) and a .csv (see attached) with several data. What I need to do is scan the entire .txt and for every station, eg. Airport, to go and scan column 14 of the .csv. If the station is the same, I want to do several things, eg. extract the date (column 2) and Temperature (column 15) every time Airport appears.
I tried with eq but it doesn't work.
list1 = rdir ('C:\Projects\LIFE ASTI\C.3\C.3\Weather station data\from desktop\Obs. data 4 Keppas\');
wrfdir = 'C:\Projects\LIFE ASTI\C.3\C.3\Weather station data\from desktop\2019 run\Thess\*.csv';
stations = readtable('C:\Projects\LIFE ASTI\C.3\C.3\Weather station data\from desktop\Stations coordinates.txt');
output_path='C:\Projects\LIFE ASTI\C.3\C.3\Weather station data\from desktop\OutputSimulations';
WRF_Data = readtable('C:\Projects\LIFE ASTI\C.3\C.3\Weather station data\from desktop\2019 run\Thess\THESS_Temp.csv');
% Variables
vars={'Temperature'; 'Relative humidity'};
years = {'2015'; '2019'};
varunits={'Celsius'; '%' };
%Starting loop for all files
for i=1:size(stations,1)
for k = 1:size(WRF_Data.Station,1)
if eq(stations(i,1) , WRF_Data.Station(k,1))

채택된 답변

Guillaume 2020년 1월 24일
I'm not entirely clear what the ultimate goal is but one thing for sure, you don't need a loop at all.
To keep only the rows of WRF_Data that have a station in stations AND append the rest of the station variables to these rows, it's simply:
merged = innerjoin(WRF_Data, stations, 'Keys', 'Station'); %And you don't even need the 'Keys', 'stations' although it makes the code clearer.
If you don't want all the variables in the output, you can tell innerjoin which one you want:
merged = innerjoin(WRF_Data, stations, 'LeftVariables', {'Station', 'Var1', 'Temp'}, 'RightVariables', {'Lat', 'Lon'}) %for example
  댓글 수: 8
Daphne PARLIARI 2020년 1월 27일
Great, thank you!
If you have time, could you please explain to me what each of line
splitapply(@(rows, statidx) writetable(merged(rows, :), sprintf('%s.csv', stations{statidx(1)})), (1:height(merged))', group, group);
Guillaume 2020년 1월 27일
splitapply split the input arrays into groups and apply the same function to each group, that is it takes the rows of each input array corresponding to a group and pass that to the function, then it passes the rows corresponding to the next group, etc.
The groups are defined by the last input to splitapply, in this case group. The two arrays that I've decided would be split are (1:height(merged))' which is basically the row indices of the table and group as I actually need the group index to be passed to the processing function. The processing function is the anonymous function: @(rows, statidx) writetable(merged(rows, :), sprintf('%s.csv', stations{statidx(1)})). This is a function with two inputs rows and statidx. rows receives in turn the elements of the first input of splitapply: (1:height(merged))', that is it receives the row indices of the table corresponding to a group (a station), statidx receives in turn the elements of the 2nd input, group corresponding to a group, so it's a vector of identical numbers, hence why I use statidx(1) in the function body.
The function body writes the sekect rows of the table to a file whose name is the station. If we were to rewrite the anonymous function, it would be more or less
function anonfun(rows, statidx)
%rows: row indices of the table corresponding to a single station. Column vector
%statidx: column vector of identical values containing the station/group number
%Unlike normal function, anonymous functions can capture variable from the enclosing workspace
%Here, it also captures
%merged: the table
%stations: list of unique station names, ordered by group number
subtable = merged(rows, :); %extract portion of the table corresponding to station
currentstation = stations{statidx(1)};
filename = sprintf('%s.csv', currentstation);
writetable(subtable, filename);
And if you were to write what splitapply does as a loop, it would be (in this case):
input1 = (1:height(merged))'; %row indices of the table
input2 = group;
for g = 1:max(group)
thisgroup_input1 = input1(group == g);
thisgroup_input2 = input2(group == g);
anonfun(thisgroup_input1, thisgroup_input2); %anonfun also captures merged and stations without needing to pass them as arguments

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Philippe Lebel
Philippe Lebel 2020년 1월 24일
편집: Philippe Lebel 2020년 1월 24일
Here you go:
I loop over all station names and check where in the data table i find these names. I generate a boolean index in order to fetch data from the table and store them in a structure.
stations = readtable('\Stations coordinates.txt');
WRF_Data = readtable('\THESS_Temp.csv');
%Starting loop for all files
for i=1:size(stations,1)
WRF_Data_station_mask = ismember(WRF_Data(:,14),stations(i,1));
sorted_values(i).name = char(stations{i,1});
sorted_values(i).temps = WRF_Data(WRF_Data_station_mask,15);


Help CenterFile Exchange에서 Tables에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by