How to combine two lists to plot coordinate pairs? - wolfram-mathematica

I have read x-data (from text files) into list1, and y-data similarly into list2:
list1 = { 0.0, 0.172, 0.266, ..}
list2 = {-5.605, -5.970, -6.505, ..}
How do I combine the two lists in order to plot points {0.0, -5.605}, {0.172, -5.970}, {0.266, -6.505},....

If you don't like Pinguin Dirk's suggestion try
Transpose[{list1,list2}]

yet another..
MapThread[ {#1, #2} & , {list1, list2}]
or if you want to gracefully handle unequal length lists:
MapThread[ {#1, #2} &, Take[#, All, Min ## Length /# #] &#{list1, list2} ]

Here is another answer that creates a reusable function to pair up two vectors. The function uses a pure function that maps over the length of the shortest vector to create the pairs.
list1 = {1, 2, 3, 4, 5};
list2 = {13, 18, 20, 18, 13};
pairUp[xValues_ , yValues_] := ({xValues[[#]], yValues[[#]]}) & /#
Range[Min[Length[xValues], Length[yValues]]];
pairUp[list1, list2]
(*
{{1, 13}, {2, 18}, {3, 20}, {4, 18}, {5, 13}}
*)
Hope this helps,
Edmund
PS: New to Mathematica and hoping to improve my understanding by trying to answer a few questions on here from time to time.

Here you go
Partition[Riffle[x,y],2]

Related

Need plot numerous sets of data, however I need to "shift" them so that they all have the same initial y value when t=0

Any Ideas on how I can accomplish this? I am very new to mathematica...
My initial thoughts were to import the data from excel in .CSV and determine the max y value in all of the sets of data, and shift the rest of the initial y values to that value. Also I need to keep the time values unchanged, and it needs to work for N# of lists.
I have no Idea how to do this, or if there is a simpler solution. Thanks!
Example:
List#1-> {{8,0},{6,1},{4,2}}, List#2-> {{7,0},{6,1},{2,2}}
List#1-> {{8,0},{6,1},{4,2}}, List#2-> {{8,0},{7,1},{3,2}}
All y values in list #2 were shifted up by one.
He has asked this question at least one other place. He seems to want to add an offset to each pair in a list so that the first of the first of all the lists become the same, the first of each pair in the rest of each list have the same offset added and the second of each pair is unchanged and he wants this to work on a relatively arbitrary number of lists.
Try to adapt this and see if it works for you
list1 = {{8, 0}, {6, 1}, {4, 2}};
list2 = {{7, 0}, {6, 1}, {2, 2}};
list3 = {{5, 0}, {7, 1}, {5, 2}};
list4 = {{9, 0}, {4, 1}, {1, 2}};
f[v_] := Map[# + {list1[[1, 1]] - v[[1, 1]], 0} &, v];
{list2, list3, list4} = Map[f, {list2, list3, list4}]
which should assign {{8,0},{7,1},{3,2}} to list2, {{8,0},{10,1},{8,2}} to list3 and {{8,0},{3,1},{0,2}} to list4.

using nested arrays and lists in mathematica

Absolute beginner question here.
I have two lists in mathematica.
The first one was generated by the Table command:
Table[QP[[i]], {i, 10}]
which generates the list:
{52.5, 45., 37.5, 30., 22.5, 15., 7.5, 0., -7.5, -15.}
the second is a Range
Range[0, 9, 1]
which generates {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
I need to get these into a list of lists. i.e. {{0,52.5},{1,45} ... } etc. But I can't seem to get it. Do you need to use loops? Because I think that what I want can be generated with the Table and Array commands.
Thanks
Transpose may be what you want:
list1 = {52.5, 45., 37.5, 30., 22.5, 15., 7.5, 0., -7.5, -15.}
list2 = Range[0, 9, 1]
Transpose[{list2, list1}]
gives
{{0, 52.5}, {1, 45.}, {2, 37.5}, {3, 30.}, {4, 22.5}, {5, 15.}, {6,
7.5}, {7, 0.}, {8, -7.5}, {9, -15.}}
The first parameter of Table can be any expression. You can have it output a list of lists, by specifying a list as the first parameter:
Table[{i-1, QP[[i]]}, {i, 10}]
(* {{0, QP[[1]]}, {1, QP[[2]]}, ... {8, QP[[9]]}, {9, QP[[10]]}} *)
Thread[List[Range[0, 9], QP[[;; 10]]]]
To complete the exposition of methods, you could use MapIndexed
MapIndexed[{First[#2] - 1,#1}&, data]
where
data = {52.5, 45., 37.5, 30., 22.5, 15., 7.5, 0., -7.5, -15.}
Or, you could use MapThread
MapThread[List, {Range[0,9], data}]
Although, MapIndexed is more appropriate since it does not require you to generate an extra list.
A last point I want to make is that your code Table[QP[[i]], {i, 10}] implies that QP itself is a list. (The double brackets, [[ ]], gave it away.) If that is correct, than Table isn't the best way to generate a subset, you can use Part ([[ ]]) along with Span directly
QP[[ 1 ;; 10 ]]
or
QP[[ ;; 10 ]]
Then, you can replace data in the first bits of code with either of those forms.

What's the best way to select the maximum one from a list of lists by their last element?

In Mathematica, Max[] is the most efficient function to get the maximum number in a list of numbers, but how do I find the list with the maximum last element in a list of lists? e.g. the 2-d coordinate with the biggest x part in a series of coordinates.
My best try is SortBy, but obviously I don't need the program to sort my list, only the maximum one I need.
Perhaps:
list = {{4, 3}, {5, 10}, {-2, 1}, {3, 7}}
Reverse /# Take[#, Ordering[#, -1]] &#(Reverse /# #) &# list
(*
-> {{5, 10}}
*)
Exploiting the fact that Ordering[ ] orders lists by their first element
Edit
Or much better (I think):
Take[#, Ordering[Last /# #, -1]] &# list
Edit
Also:
#[[Ordering[#, -1, Last##2 > Last##1 &]]] &#list
Edit
Perhaps faster:
#[[First#Position[#, Max##] &#(Last /# #)]] &#list
Here is my approach using Pick
maxBy[list_, n_] := With[{s = list[[All, n]]}, Pick[list, s, Max[s]]]
maxBy[{{4, 3}, {5, 10}, {-2, 1}, {3, 7}}, 2]
(* output:
{{5, 10}}
*)
This version works on any number of elements per sublist provided n is less than or equal to the length of the shortest sublist.
Timings for this version on my machine
list2 = RandomInteger[{-10^7, 10^7}, {10^6, 2}];
list3 = RandomInteger[{-10^7, 10^7}, {10^6, 3}];
list9 = RandomInteger[{-10^7, 10^7}, {10^6, 9}];
maxBy[list2, 2]; // Timing
maxBy[list3, 2]; // Timing
maxBy[list9, 2]; // Timing
(* output:
{0.030341, Null}
{0.030912, Null}
{0.033313, Null}
*)
Compared to David's code
maxBy[list2, 2]; // Timing
maxBy[list3, 2]; // Timing
maxBy[list9, 2]; // Timing
(* ouput:
{0.186175, Null}
{0.184989, Null}
{0.262018, Null}
*)
Yoda's code
maxBy[list2, 2]; // Timing
maxBy[list3, 2]; // Timing
maxBy[list9, 2]; // Timing
(* ouput:
{0.944016, Null}
{0.83094, Null}
{0.874126, Null}
*)
And belisarius' code
Reverse /# Take[#, Ordering[#, -1]] &#(Reverse /# #) &#list2; // Timing
Take[#, Ordering[Last /# #, -1]] &#list2; // Timing
#[[Ordering[#, -1, Last##2 > Last##1 &]]] &#list2; // Timing
#[[First#Position[#, Max##] &#(Last /# #)]] &#list2; // Timing
(* output:
{0.211016, Null}
{0.099253, Null}
{2.03415, Null}
{0.266934, Null}
*)
Not the most efficient but simpler?
max = Max#list[[All, -1]];
Cases[list, {_, max}]
or
max = Max#list3[[All, -1]];
Cases[list3, {_,_, max}]
Usage
list = {{40, 3}, {5, 10}, {-2, 1}, {3, 10}}
max = Max#list[[All, -1]];
Cases[list, {_, max}]
Output:
{{5, 10}, {3, 10}}
How about this function (defined here only for 2D lists):
maxBy = Module[{pattern = Reverse#Insert[{Max##1[[All, #2]]}, _, #2]},
Cases[#1, pattern]] &
Example:
list = {{4, 3}, {5, 10}, {20, 1}, {3, 7}};
maxBy[list, 1]
Out[1]= {{20, 1}}
maxBy[list, 2]
Out[2]= {{5, 10}}
Here's an approach that relies on Transpose:
maxBy = #1[[Position[t = Transpose[#1][[#2]], Max[t]][[All, 1]]]] &;
For example:
list = {{4, 3}, {5, 10}, {20, 1}, {3, 7}};
maxBy[list, 1]
(* {{20, 1}} *)
maxBy[list, 2]
(* {{5, 10}} *)
It can handle more than two elements per sublist, provided that the sublists are all the same length.
r:=RandomInteger[{-10^5,10^5}];
list3=Table[{r,r,r},{j,10^2}]; (* 3 numbers in each sublist *)
list9=Table[{r,r,r,r,r,r,r,r,r},{j,10^2}]; (* 9 numbers *)
maxBy[list3, 2] (* Find max in position 2 of list3 *)
(* {{-93332, 99582, 4324}} *)
maxBy[list9, 5] (* Find max in position 5 of list9 *)
(* {{7680, 85508, 51915, -58282, 94679, 50968, -12664, 75246, -82903}} *)
Of course, the results will vary according to the random numbers you have generated.
Edit
Here's some timing data for large lists. SortBy is clearly slower. but doesn't seem as influenced by the number of elements in each sublist. First, my maxBy code followed by SortBy:
Using the same list2, here's some timing data for Yoda's code. Although his routine is also called maxBy, it is his that produced the output that follows:
Again, with the same list2, some data for Belisarius' code:
His second suggestion is the fastest of all tested.
After reading some documentations and doing a few experiments, I managed to get a clearer view of this problem.
I actually was wondering why Max[] seemed intentionally avoid providing directives that make it return not only the max element itself, but also its position. After all, providing position doesn't change the O(n) complexity of the algorithm. For example, imagine:
In[1]:= Max[{991, 993, 992}, ReturnPosition -> True]
Out[1]= {2}
If that could be done, you can simply use the code below to solve my problem:
list[[Max[list[[All, -1]], ReturnPosition -> True]]]
But now I realize that the system function Max[] is not designed for finding the max element in lists. You can tell that the Wolfram team obviously made Max[] more like a traditional max function in mathematics ― it does simple symbolic simplifications, it automatically flatten out all lists, it can be in a plotable function, and most importantly, it's Orderless:
In[2]:= Attributes[Max]
Out[2]= {Flat, NumericFunction, OneIdentity, Orderless, Protected}
Which makes positions meaningless. In a word, it treats all the lists inside as mathematical sets.
So philosophically it's not trivial for Mathematica to compute this. All I need to do is to "DIY" a function with the O(n) complexity and can do the job. I think TomD is heading the right direction, although I prefer:
maxLast[l_] := Cases[l, {___, Max[Last/#l]}]
And Heike (黑客?) adopted Pick which may have better techniques especially designed for selecting elements, but there must be no virtual difference in the complexity of the algorithm. And I may rewrite it this way: (fewer names and heads, faster the speed)
maxLast[l_] := Pick[l, #, Max[#]] &[Last /# l]
They're both good answers.

Changing values in nested lists according to elements in the list

I have a list of pairs of values in mathematica, for example List= {{3,1},{5,4}}.
How do I change the first element (3 & 5) if the second element does not reach a threshold. For example, if the second parts are below 2 then i wish the first parts to go to zero. so that list then = {{0,1},{5,4}}. Some of these lists are extremely long so manually doing it is not an option, unfortunately.
Conceptually, the general way is to use Map. In your case, the code would be
In[13]:= lst = {{3, 1}, {5, 4}}
Out[13]= {{3, 1}, {5, 4}}
In[14]:= thr = 2
Out[14]= 2
In[15]:= Map[{If[#[[2]] < thr, 0, #[[1]]], #[[2]]} &, lst]
Out[15]= {{0, 1}, {5, 4}}
The # symbol here stands for the function argument. You can read more on pure functions here. Double square brackets stand for the Part extraction. You can make it a bit more concise by using Apply on level 1, which is abbreviated by ###:
In[27]:= {If[#2 < thr, 0, #], #2} & ### lst
Out[27]= {{0, 1}, {5, 4}}
Note however that the first method is several times faster for large numerical lists. An even faster, but somewhat more obscure method is this:
In[29]:= Transpose[{#[[All, 1]]*UnitStep[#[[All, 2]] - thr], #[[All, 2]]}] &[lst]
Out[29]= {{0, 1}, {5, 4}}
It is faster because it uses very optimized vectorized operations which apply to all sub-lists at once. Finally, if you want the ultimate performance, this procedural compiled to C version will be another factor of 2 faster:
fn = Compile[{{lst, _Integer, 2}, {threshold, _Real}},
Module[{copy = lst, i = 1},
For[i = 1, i <= Length[lst], i++,
If[copy[[i, 2]] < threshold, copy[[i, 1]] = 0]];
copy], CompilationTarget -> "C", RuntimeOptions -> "Speed"]
You use it as
In[32]:= fn[lst, 2]
Out[32]= {{0, 1}, {5, 4}}
For this last one, you need a C compiler installed on your machine.
Another alternative: Apply (###, Apply at level 1) and Boole (turns logical values in 1's and 0's):
lst = {{3, 1}, {5, 4}};
{#1 Boole[#2 >= 2], #2} & ### lst
An alternative approach might be to use substitution rules, and attach a condition (/;)
lst = {{3, 1}, {5, 4}};
lst /. {x_, y_ /; y < 2} -> {0, y}
output:
{{0, 1}, {5, 4}}
Assuming that your matrix is 2x2 and by second elemnt you mean the second row:
This should work:
If[A[[2, 1]] < 2 || A[[2, 2]] < 2, A[[2,1]] = 0 ]; A
You may have to change the variables, since your questions is kind of confusing. But that's the idea ;-)

Alternative form of FactorInteger? (Mathematica)

In Mathematica
a = FactorInteger[44420069694]
assigns
{{2, 1}, {3, 1}, {7, 1}, {11, 2}, {13, 1}, {23, 2}, {31, 1}, {41, 1}}
to a. Now instead of the factors with their exponents I would like each of those lists expanded. The above factorization would then become
{2, 3, 7, 11, 11, 13, 23, 23, 31, 41}
I wrote the following function:
b = {}; Do[Do[b = Append[b, a[[i]][[1]]], {a[[i]][[2]]}], {i, Length[a]}]
but if you ask me it looks fugly. There sure must be a neater way to do achieve this?
Yes, for example:
Flatten[Map[Table[#[[1]], {#[[2]]}] &, a]]
Yet another way in Mathematica 6 or later.
In:= Flatten[ConstantArray ### a]
Out={2, 3, 7, 11, 11, 13, 23, 23, 31, 41}
even shorter:
Join ## ConstantArray ### a
A speed comparison of methods posted
Using the these functions (in the order they were posted):
zvrba = Flatten[Map[Table[#[[1]], {#[[2]]}] &, #]] &;
dreeves = Sequence ## Table[#1, {#2}] & ### # &;
gdelfino = Flatten[# /. {p_, n_} :> Table[p, {n}]] &;
mrwizard = Join ## ConstantArray ### # &;
sasha = Function[{p, e}, Array[p &, e, 1, Sequence]] ### # &;
and assigning them the letters Z, D, G, M, S respectively, here are Timing charts of their efficiency.
First, for increasing number of lists in the input:
Second, for increasing exponent (length of repetition) in each list:
Note that these charts are logarithmic. Lower is better.
Here's another way to do it:
rptseq[x_, n_] := Sequence ## Table[x, {n}]
rptseq ### a
Which can be condensed with a lambda function to:
Sequence ## Table[#1, {#2}] & ### a
zvrba's answer can also be condensed a bit, if you're into that sort of thing:
Flatten[Table[#1, {#2}]& ### a]
(Now that I look at that, I guess my version is a very minor variant on zvrba's.)
You could also use:
a /. {p_, n_} -> Table[p, {n}] // Flatten
UPDATE 2017/10/18:
My answer above fails "in the case of two distinct prime factors" as pointed out by Cory Walker. This update fixes it:
a /. {p_Integer, n_Integer} -> Table[p, {n}] // Flatten
notice that the benchmark done by Mr Wizard was done with the original version before this update.
One can also use Array to process the answer. Here is a short code doing this:
In[11]:= PrimeFactorInteger[i_Integer] :=
Function[{p, e}, Array[p &, e, 1, Sequence]] ### FactorInteger[i]
In[12]:= PrimeFactorInteger[2^3 3^2 5]
Out[12]= {2, 2, 2, 3, 3, 5}

Resources