Not nearly as clean as KraZug's method but a bit faster, if it matters
getReal = Pick[#, Unitize[Abs@Im@#.{1, 1}], 0] &;
getReal[data]
{{1, 3}, {-5, 0}, {3, 6}}
Timings:
big = Join[RandomReal[{-9, 9}, {5000, 2}],
RandomComplex[{-2 - I, 5 + 3 I}, {3000, 2}]] // RandomSample;
Select[big, And @@ Internal`RealValuedNumberQ /@ # &] // Length // RepeatedTiming
Select[big, FreeQ[#, Complex] &] // Length // RepeatedTiming
getReal[big] // Length // RepeatedTiming
{0.017, 5000}
{0.0097, 5000}
{0.0072, 5000}
Packed arrays
I chose Pick
because it is fast on packed arrays, forgetting that the format I chose for big
would not be packed. This makes my method significantly less competitive as seen in Shadowray's answer. However there is a case where it is much faster, even if that case now seems a little contrived. If we force packing of big
as Complex data getReal
demonstrates the performance I was aiming for. This can be followed by conversion to packed Real to clear out the 0. I
terms. On the question example that looks like this:
Developer`ToPackedArray[data, Complex];
getReal[%]
Developer`ToPackedArray[%, Real]
{{1. + 0. I, 3. + 0. I}, {-5. + 0. I, 0. + 0. I}, {3. + 0. I, 6. + 0. I}}
{{1., 3.}, {-5., 0}, {3., 6.}}
If the ultimate target of this filtering is ListDensityPlot
this format will be fine.
I cannot directly compare the performance of getReal
on this packed Complex to other methods such as Select[FreeQ[Complex]]
and Cases[data, {_Real | _Integer, _Real | _Integer}]
as these won't work on the packed data. I shall therefore compare their performance on unpacked big
to getReal
on the packed form I'll name big2
.
big2 = Developer`ToPackedArray[big, Complex];
Select[big, FreeQ[#, Complex] &] // Length // RepeatedTiming
Cases[big, {_Real | _Integer, _Real | _Integer}] // Length // RepeatedTiming
Developer`ToPackedArray[getReal[big2], Real] // Length // RepeatedTiming
{0.0162, 5000}
{0.01, 5000}
{0.00114, 5000}
{0.00019, 5000}
This doesn't include the initial conversion to packed Complex, which itself takes:
Developer`ToPackedArray[big, Complex]; // RepeatedTiming
{0.00029, Null}
So with that overhead my code is 114 / (19 + 29) ~= 2.3 times faster than Shadowray's next-fastest code, and without that overhead it is almost four times faster.
dataReal = DeleteCases[data, _?(! FreeQ[#, Complex] &)]
$\endgroup$