Fastest/cleanest way to pad data with zero-data
Why not use Dot
and ArrayReshape
on the original data
:
data = Developer`ToPackedArray @ Table[
{x, Sin[x]},
{x, 0, 2Pi, .0001}
];
Then:
ArrayReshape[
data . {{1, 0, 1, 0, 1, 0}, {0, 0, 0, 1, 0, 0}},
{Length[data] 3, 2}
]; //RepeatedTiming
{0.000397, Null}
One reason for slowness is that the input data was not packed. Moreover Transpose
is often faster than Riffle
:
{xdata, ydata} = Transpose[Map[x \[Function] {x, Sin[x]}, Range[0., 2 Pi, .0001]]];
f[xdata_, ydata_] := Transpose[{
Flatten[Transpose[ConstantArray[xdata, 3]]],
With[{o = ConstantArray[0., Length[ydata]]},
Flatten[Transpose[{o, ydata, o}]]
]
}]
a = zeroPaddedData[xdata, ydata]; // RepeatedTiming // First
b = f[xdata, ydata]; // RepeatedTiming // First
a == b
0.030
0.00165
True
Slower but simple
tab = Table[{x, Sin[x]}, {x, 0, 2 Pi, .5}];
SequenceReplace[tab, {{a_,b_}}:>Sequence[{a,0},{a,b},{a,0}]] == zpd
True
Update: Using Upsample
on the second argument gives a slight improvement over Henrik's f
:
ClearAll[zPad]
zPad[xd_, yd_] := Transpose[{Flatten[ConstantArray[xd, 3], {2, 1}], Upsample[yd, 3, 2]}];
{xdata, ydata} = Transpose[Map[x \[Function] {x, Sin[x]}, Range[0., 2 Pi, .0001]]];
a = zeroPaddedData[xdata, ydata]; // RepeatedTiming // First
0.024
b = f[xdata, ydata]; // RepeatedTiming // First
0.0017
c = zPad[xdata, ydata]; // RepeatedTiming // First
0.0016
a == b == c
True
Interesting to note that although Upsample
is almost twice as fast as With[{o = ConstantArray[0., Length[ydata]]}, Flatten[Transpose[{o, ydata, o}] ]]
this advantage is not retained when combined with other steps:
r1 = Upsample[ydata, 3, 2] ; // RepeatedTiming // First
0.00061
r2 = With[{o = ConstantArray[0., Length[ydata]]},
Flatten[Transpose[{o, ydata, o}] ]]; // RepeatedTiming // First
0.0013
r1 == r2
True