using nested arrays and lists in mathematica - wolfram-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.

Related

How do I apply Map[] to a function using two arguments in Mathematica?

In general, I was trying to compute the norm of the difference between every set two elements in a list which looks something like
X = {{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15}}
therefore evaluating
Norm[X[[1]]-X[[2]]]
Norm[X[[1]]-X[[3]]]
Norm[X[[2]]-X[[3]]]
Now, applying Outer[] is one possible way how to do this
Outer[Norm[X[[#1]] - X[[#2]]] &, {1,2,3}, {1,2,3}]
but unfortunately it results in a quite slow code if I increase the number of elements in X and the length of each element.
Is there any possible way to construct a Map[] operation? Something like
MapThread[Norm[X[[#1]] - X[[#2]]] &,{{1,2,3},{1,2,3}}]
does not work give the desired "currying" which I was looking for.
I'm using Mathematica Version 11.2.0.0, so I don't have access to Curry[].
Would be happy about any advice!
mX = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}, {11, 12, 13, 14, 15}}
Apply[Norm#*Subtract, #] & /# Subsets[mX, {2}]
Two equivalent approaches:
(Norm#*Subtract) ### Subsets[mX, {2}]
Apply[Norm#*Subtract, Subsets[mX, {2}], {1}]

binning an array to create sum domains array

In Mathematica - how do I bin an array to create a new array which consist from sum domains of the old array with a given size ???
Example:
thanks.
This is slightly simpler than #ChrisDegnen's solution. Given the same definition of array the expression
Map[Total, Map[Flatten, Partition[array, {2, 2}], {2}], {2}]
produces
{{4, 10}, {8, 10}}
If you prefer, this expression
Apply[Plus, Map[Flatten, Partition[array, {2, 2}], {2}], {2}]
uses Apply and Plus rather than Map and Total but is entirely equivalent.
This works for the example but a generalised version would need more work.
array =
{{1, 1, 1, 2},
{1, 1, 3, 4},
{2, 2, 2, 3},
{2, 2, 2, 3}};
Map[Total,
Map[Flatten,
Map[Transpose,
Map[Partition[#, 2] &, Partition[array, 2], 2],
2], {2}], {2}]
% // MatrixForm
4 10
8 10

How to combine two lists to plot coordinate pairs?

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]

Fast extraction of elements from nested lists

This is a basic question on list manipulation in Mathematica.
I have a large list where each element has the following schematic form: {List1, List2,Number}. For e.g.,
a = {{{1,2,3},{1,3,2},5},{{1,4,5},{1,0,2},10},{{4,5,3},{8,3,4},15}}}.
I want to make a new lists which only has some parts from each sublist. Eg., pick out the third element from each sublist to give {5,10,15} from the above. Or drop the third element to return {{{1,2,3},{1,3,2}},{{1,4,5},{1,0,2}},{{4,5,3},{8,3,4}}}.
I can do this by using the table command to construct new lists, e.g.,
Table[a[[i]][[3]],{i,1,Length[a]}
but I was wondering if there was a must faster way which would work on large lists.
In Mathematica version 5 and higher, you can use the keyword All in multiple ways to specify a list traversal.
For instance, instead of your Table, you can write
a[[All,3]]
Here Mathematica converts All into all acceptable indices for the first dimension then takes the 3rd one of the next dimension.
It is usually more efficient to do this than to make a loop with the Mathematica programming language. It is really fine for homogenous lists where the things you want to pick or scan through always exist.
Another efficient notation and shortcut is the ;; syntax:
a[[ All, 1 ;; 2]]
will scan the first level of a and take everything from the 1st to the 2st element of each sublist, exactly like your second case.
In fact All and ;; can be combined to any number of levels. ;; can even be used in a way similar to any iterator in Mathematica:
a[[ start;;end;;step ]]
will do the same things as
Table[ a[[i]], {i,start,end,step}]
and you can omit one of start, end or step, it is filled with its default of 1, Length[(of the implicit list)], and 1.
Another thing you might want to lookup in Mathematica's Help are ReplacePart and MapAt that allow programmatic replacement of structured expressions. The key thing to use this efficiently is that in ReplacePart you can use patterns to specify the coordinates of the things to be replaced, and you can define functions to apply to them.
Example with your data
ReplacePart[a, {_, 3} -> 0]
will replace every 3rd part of every sublist with 0.
ReplacePart[a, {i : _, 3} :> 2*a[[i, 3]]]
will double every 3rd part of every sublist.
As the authors suggest, the approaches based on Part need well-formed data, but Cases is built for robust separation of Lists:
Using your a,
a = {{{1, 2, 3}, {1, 3, 2}, 5}, {{1, 4, 5}, {1, 0, 2},
10}, {{4, 5, 3}, {8, 3, 4}, 15}};
Cases[a,{_List,_List,n_}:>n,Infinity]
{5, 10, 15}
The other pieces of a record can be extracted by similar forms.
Part-based approaches will gag on ill-formed data like:
badA = {{{1, 2, 3}, {1, 3, 2}, 5}, {{1, 4, 5}, {1, 0, 2},
10}, {{4, 5, 3}, {8, 3, 4}, 15}, {baddata}, {{1, 2, 3}, 4}};
badA[[All,3]]
{{{1, 2, 3}, {1, 3, 2}, 5}, {{1, 4, 5}, {1, 0, 2},
10}, {{4, 5, 3}, {8, 3, 4}, 15}, {baddata}, {{1, 2, 3},
4}}[[All, 3]]
,but Cases will skip over garbage, operating only on conforming data
Cases[badA, {_List, _List, s_} :> s, Infinity]
{5, 10, 15}
hth,
Fred Klingener
You can use Part (shorthand [[...]]) for this :
a[[All, 3]]
a[[All, {1, 2}]]

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