The challenge is following:
There are two lists data1
and data2
of following type:
data1 = {{t11,X1},{t12,X2},{t13,X3}, ... ,{t1n,Xn}};
data2 = {{t21,Y1},{t22,Y2},{t23,Y3}, ... ,{t2m,Ym}};
The first coordinate in both lists is of the same type, in my case it is time. The second coordinates are different: for example, X is temperature and Y is viscosity. The number of elements in both lists is different: n ~ 10^4
and m ~ 10^7
.
The task is to check whether the temperature was constant through out the whole experiment and filter out the viscosity measurements recorded within +/-10s time windows for all these deviations.
So, a suggested algorithm is following:
1. To check whether condition Xi == T
is True
for all elements of data1
, where T
is a constant value.
2. Do nothing if the condition is True
3. If the condition is False
for i = k
:
3.1 Determine the t1k
,
3.2 Set up an interval (t1k-10;t1k+10)
3.3 Delete the values Yi
that were recorded within this interval
I have performed the straightforward solution applying a number of Do
cycles and If
type conditions just according to the algorithm. It works but it takes a huge amount of computational time to solve, especially when dealing with large number of lists.
Perhaps there is a more efficient way?
Here is the link for an example data, as requested.
Comparing calculation times:
Original (slow) solution -- applied to the example data files took 6 min to compute.
dataClean = Block[ {sTfI, loT, datafrmod, xx, T}, T = 40; sTfI = Cases[data1, {_, T}][[{1, -1}, 1]]; loT = Select[data1, #[[1]] >= sTfI[[1]] && #[[1]] <= sTfI[[2]] &]; datafrmod = Select[data2, #[[1]] > (loT[[1, 1]] + 5.) && #[[1]]<(loT[[-1, 1]] - 5.) &]; xx = DeleteDuplicates[ Select[loT, #[[2]] != T &][[;; , 1]], (Abs[#1 - #2] < 5. &)]; Do[datafrmod = Join[Select[datafrmod, #[[1]] < (xx[[i]] - 10) &], Select[datafrmod, #[[1]] > (xx[[i]] + 10) &]], {i, Length[xx]}]; datafrmod ]; // AbsoluteTiming
Solution by Coolwater was much faster but still took 50 sec to compute.
data = Block[ {T, which}, T = 40; which = With[{tsBad = Extract[data1[[All, 1]], Position[data1[[All, 2]], Except[T], {1}, Heads -> False]]}, Complement[Range[Length[data2]], ##] & @@ Nearest[data2[[All, 1]] -> "Index", tsBad, {\[Infinity], 10}]]; data2[[which]] ]; // AbsoluteTiming
Is it the limit for the efficiency?
data1
anddata2
the same length or not? How is it possible that the time stamps indata2
run up tot2n
while the viscosities run up toYm
, withn
andm
different? $\endgroup$data2
time coordinates are a mix of reals and integers. This is why Nearest is slow. UseNearest[N @ data2[[All, 1]] -> "Index" , tsBad, {Infinity, 10}]
instead and it will be much faster. Even faster isNearest[Developer`ToPackedArray @ N @ data2[[All, 1]] -> "Index", tsBad, {Infinity, 10}]
$\endgroup$