6
$\begingroup$

I have data such as

testdatax = {{49, 62, 24, 10, 79, 78, 14, 76, 44, 91}, {76, 93, 36, 65, 6, 74, 57, 14, 96, 6}, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}};

testdatay = {{{28, 44, 43, 3, 42, 30, 41, 34, 0, 48}, {7, 10, 19, 12, 3, 20, 16, 7, 19, 11}, {2, 11, 7, 13, 27, 27, 9, 0, 22, 16}}, {{3, 42, 45, 28, 28, 20, 13, 1, 43, 29}, {13, 23, 5, 9, 5, 7, 20, 1, 20, 25}}, {{14, 0, 38, 38, 12, 1, 2, 47, 31, 32}, {13, 11, 9, 15, 6, 4, 20, 4, 15, 7}, {24, 10, 0, 25, 23, 21, 16, 29, 2, 17}, {21, 46, 50, 36, 27, 37, 50, 23, 0, 27}, {14, 14, 0, 15, 15, 0, 10, 2, 14, 19}, {26, 11, 17, 2, 13, 22, 28, 5, 3, 7}}};

where the length of sublist in test data y is different.

Since I want to plot the data, I'd like to get this answer list,

answer={{{{49, 28}, {62, 44}, {24, 43}, {10, 3}, {79, 42}, {78, 30}, {14, 
41}, {76, 34}, {44, 0}, {91, 48}}, {{49, 7}, {62, 10}, {24, 
19}, {10, 12}, {79, 3}, {78, 20}, {14, 16}, {76, 7}, {44, 
19}, {91, 11}}, {{49, 2}, {62, 11}, {24, 7}, {10, 13}, {79, 
27}, {78, 27}, {14, 9}, {76, 0}, {44, 22}, {91, 16}}}, {{{76, 
3}, {93, 42}, {36, 45}, {65, 28}, {6, 28}, {74, 20}, {57, 
13}, {14, 1}, {96, 43}, {6, 29}}, {{76, 13}, {93, 23}, {36, 
5}, {65, 9}, {6, 5}, {74, 7}, {57, 20}, {14, 1}, {96, 20}, {6, 
25}}}, {{{1, 14}, {2, 0}, {3, 38}, {4, 38}, {5, 12}, {6, 1}, {7, 
2}, {8, 47}, {9, 31}, {10, 32}}, {{1, 13}, {2, 11}, {3, 9}, {4, 
15}, {5, 6}, {6, 4}, {7, 20}, {8, 4}, {9, 15}, {10, 7}}, {{1, 
24}, {2, 10}, {3, 0}, {4, 25}, {5, 23}, {6, 21}, {7, 16}, {8, 
29}, {9, 2}, {10, 17}}, {{1, 21}, {2, 46}, {3, 50}, {4, 36}, {5, 
27}, {6, 37}, {7, 50}, {8, 23}, {9, 0}, {10, 27}}, {{1, 14}, {2, 
14}, {3, 0}, {4, 15}, {5, 15}, {6, 0}, {7, 10}, {8, 2}, {9, 
14}, {10, 19}}, {{1, 26}, {2, 11}, {3, 17}, {4, 2}, {5, 13}, {6, 
22}, {7, 28}, {8, 5}, {9, 3}, {10, 7}}}};

I could get this anser by

answer={Transpose[{testdatax[[1]], #}] & /@ testdatay[[1]], Transpose[{testdatax[[2]], #}] & /@ testdatay[[2]], Transpose[{testdatax[[3]], #}] & /@ testdatay[[3]]};

However, this doesn't make sense when the data size becomes much larger. So I want to write in smater way like using Thread or Map. I cannot operate transpose to the sublist... Does anyone tell me how to write script in better way??

$\endgroup$

6 Answers 6

6
$\begingroup$

How to get to the bottom of things: Compile has the right sort of threading built in.

Compile[{{x, _Integer, 1}, {y, _Integer, 1}},
   Transpose@{x, y},
   RuntimeAttributes -> {Listable}
   ][testdatax, testdatay] == answer

(*  True  *)

Caveat: Types are restricted in Compile[].

$\endgroup$
1
  • $\begingroup$ Thank you very much!! Not only I could get the answer for this sample data, but also my experimental data (larger demension). Thanks to your comment, I changed "_Integer" to "_Real" for it. $\endgroup$
    – rani
    Commented Nov 29 at 7:07
5
$\begingroup$

Another way to do this is as follows:

f = Map[Thread]@Thread[{ConstantArray[#1, Length@#2], #2} & @@ #] &;

(f /@ Transpose[{testdatax, testdatay}]) === answer

(*True*)
$\endgroup$
1
  • $\begingroup$ Thank you very much for telling me the way of using ConstantArray and Thread! $\endgroup$
    – rani
    Commented Nov 29 at 7:07
4
$\begingroup$
(f |-> Transpose[{#[[1]], f}]) /@ #[[2]] & /@ 
 Transpose[{testdatax, testdatay}]
$\endgroup$
1
  • $\begingroup$ Thank you so much for giving me the answer. It was helpful. $\endgroup$
    – rani
    Commented Nov 29 at 7:08
4
$\begingroup$
MapThread[Inner[Reverse@*List, ##, List] &, {testdatay, testdatax}]

Or point-free:

MapThread[CurryApplied[Inner, {1, 3, 4, 2}][Reverse@*List, List], {testdatay, testdatax}]
$\endgroup$
1
  • $\begingroup$ Thank you so much for telling me the way to solve. This is my first time to know the way of "CurryApplied" and "Inner" usage! $\endgroup$
    – rani
    Commented Nov 29 at 7:17
4
$\begingroup$

You can leverage a Listable function together with Threaded:

testdatax = {{49, 62, 24, 10, 79, 78, 14, 76, 44, 91}, {76, 93, 36, 
    65, 6, 74, 57, 14, 96, 6}, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}};
testdatay = {{{28, 44, 43, 3, 42, 30, 41, 34, 0, 48}, {7, 10, 19, 12, 
     3, 20, 16, 7, 19, 11}, {2, 11, 7, 13, 27, 27, 9, 0, 22, 
     16}}, {{3, 42, 45, 28, 28, 20, 13, 1, 43, 29}, {13, 23, 5, 9, 5, 
     7, 20, 1, 20, 25}}, {{14, 0, 38, 38, 12, 1, 2, 47, 31, 32}, {13, 
     11, 9, 15, 6, 4, 20, 4, 15, 7}, {24, 10, 0, 25, 23, 21, 16, 29, 
     2, 17}, {21, 46, 50, 36, 27, 37, 50, 23, 0, 27}, {14, 14, 0, 15, 
     15, 0, 10, 2, 14, 19}, {26, 11, 17, 2, 13, 22, 28, 5, 3, 7}}};
Function[{a, b}, {a, b}, Listable][Threaded /@ testdatax, testdatay]

{{{{49, 28}, {62, 44}, {24, 43}, {10, 3}, {79, 42}, {78, 30}, {14, 
    41}, {76, 34}, {44, 0}, {91, 48}}, {{49, 7}, {62, 10}, {24, 
    19}, {10, 12}, {79, 3}, {78, 20}, {14, 16}, {76, 7}, {44, 
    19}, {91, 11}}, {{49, 2}, {62, 11}, {24, 7}, {10, 13}, {79, 
    27}, {78, 27}, {14, 9}, {76, 0}, {44, 22}, {91, 16}}}, {{{76, 
    3}, {93, 42}, {36, 45}, {65, 28}, {6, 28}, {74, 20}, {57, 
    13}, {14, 1}, {96, 43}, {6, 29}}, {{76, 13}, {93, 23}, {36, 
    5}, {65, 9}, {6, 5}, {74, 7}, {57, 20}, {14, 1}, {96, 20}, {6, 
    25}}}, {{{1, 14}, {2, 0}, {3, 38}, {4, 38}, {5, 12}, {6, 1}, {7, 
    2}, {8, 47}, {9, 31}, {10, 32}}, {{1, 13}, {2, 11}, {3, 9}, {4, 
    15}, {5, 6}, {6, 4}, {7, 20}, {8, 4}, {9, 15}, {10, 7}}, {{1, 
    24}, {2, 10}, {3, 0}, {4, 25}, {5, 23}, {6, 21}, {7, 16}, {8, 
    29}, {9, 2}, {10, 17}}, {{1, 21}, {2, 46}, {3, 50}, {4, 36}, {5, 
    27}, {6, 37}, {7, 50}, {8, 23}, {9, 0}, {10, 27}}, {{1, 14}, {2, 
    14}, {3, 0}, {4, 15}, {5, 15}, {6, 0}, {7, 10}, {8, 2}, {9, 
    14}, {10, 19}}, {{1, 26}, {2, 11}, {3, 17}, {4, 2}, {5, 13}, {6, 
    22}, {7, 28}, {8, 5}, {9, 3}, {10, 7}}}}

testdatax and testdatay have matching leading and trailing dimensions, but testdatay has an additional level in between. A Listable function pairs matching leading dimensions, and Threaded lists are matched to trailing dimensions.

You could alternatively reshape testdatay to make its leading dimensions agree with those of testdatax, then reshape again to achieve the desired result:

Thread /@ 
 Function[{a, b}, {a, b}, Listable][testdatax, Thread /@ testdatay]

{{{{49, 28}, {62, 44}, {24, 43}, {10, 3}, {79, 42}, {78, 30}, {14, 
    41}, {76, 34}, {44, 0}, {91, 48}}, {{49, 7}, {62, 10}, {24, 
    19}, {10, 12}, {79, 3}, {78, 20}, {14, 16}, {76, 7}, {44, 
    19}, {91, 11}}, {{49, 2}, {62, 11}, {24, 7}, {10, 13}, {79, 
    27}, {78, 27}, {14, 9}, {76, 0}, {44, 22}, {91, 16}}}, {{{76, 
    3}, {93, 42}, {36, 45}, {65, 28}, {6, 28}, {74, 20}, {57, 
    13}, {14, 1}, {96, 43}, {6, 29}}, {{76, 13}, {93, 23}, {36, 
    5}, {65, 9}, {6, 5}, {74, 7}, {57, 20}, {14, 1}, {96, 20}, {6, 
    25}}}, {{{1, 14}, {2, 0}, {3, 38}, {4, 38}, {5, 12}, {6, 1}, {7, 
    2}, {8, 47}, {9, 31}, {10, 32}}, {{1, 13}, {2, 11}, {3, 9}, {4, 
    15}, {5, 6}, {6, 4}, {7, 20}, {8, 4}, {9, 15}, {10, 7}}, {{1, 
    24}, {2, 10}, {3, 0}, {4, 25}, {5, 23}, {6, 21}, {7, 16}, {8, 
    29}, {9, 2}, {10, 17}}, {{1, 21}, {2, 46}, {3, 50}, {4, 36}, {5, 
    27}, {6, 37}, {7, 50}, {8, 23}, {9, 0}, {10, 27}}, {{1, 14}, {2, 
    14}, {3, 0}, {4, 15}, {5, 15}, {6, 0}, {7, 10}, {8, 2}, {9, 
    14}, {10, 19}}, {{1, 26}, {2, 11}, {3, 17}, {4, 2}, {5, 13}, {6, 
    22}, {7, 28}, {8, 5}, {9, 3}, {10, 7}}}}
$\endgroup$
1
  • $\begingroup$ Thank you very much for telling me in detail! I could get the result which I wanted. This tutorial is very nice and understandable for beginner like me. I also checked your answer of another question, and I voted "This answer is useful" there, too. $\endgroup$
    – rani
    Commented Nov 29 at 7:16
3
$\begingroup$
res = Table[
  Transpose /@ 
   Thread[{Table[testdatax[[i]], Length@testdatay[[i]]] , 
     testdatay[[i]]}], {i, Length@testdatax}]

res == answer

True

$\endgroup$
1
  • 1
    $\begingroup$ Thank you very much! $\endgroup$
    – rani
    Commented Dec 1 at 7:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.