binning an array to create sum domains array - image

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

Related

Efficiently generating "subtraction chains"

I posted another question earlier if you want some context. It appears that I was on the wrong path with that approach.
Addition chains can be used to minimize the number of multiplications needed to exponentiate a number. For example, a7 requires four multiplications. Two to compute a2=a×a and a4=a2×a2, and another two to compute a7=a4×a2×a.
Similarly, I'm trying to generate all of the possible "subtraction chains" for a set of numbers. For example, given the set of numbers {1, 2, 3}, I'm trying to generate the following permutations.
{1, 2, 3}
{1, 2, 3}, {1, 2}
{1, 2, 3}, {1, 2}, {1}
{1, 2, 3}, {1, 2}, {2}
{1, 2, 3}, {1, 2}, {1}, {2}
{1, 2, 3}, {1, 3}
{1, 2, 3}, {1, 3}, {1}
{1, 2, 3}, {1, 3}, {3}
{1, 2, 3}, {1, 3}, {1}, {3}
{1, 2, 3}, {2, 3}
{1, 2, 3}, {2, 3}, {2}
{1, 2, 3}, {2, 3}, {3}
{1, 2, 3}, {2, 3}, {2}, {3}
{1, 2, 3}, {1, 2}, {1, 3}
{1, 2, 3}, {1, 2}, {1, 3}, {1}
{1, 2, 3}, {1, 2}, {1, 3}, {2}
{1, 2, 3}, {1, 2}, {1, 3}, {3}
{1, 2, 3}, {1, 2}, {1, 3}, {1}, {2}
{1, 2, 3}, {1, 2}, {1, 3}, {1}, {3}
{1, 2, 3}, {1, 2}, {1, 3}, {2}, {3}
{1, 2, 3}, {1, 2}, {1, 3}, {1}, {2}, {3}
# and so on...
Where each element in the permutation (besides {1, 2, 3}) can be found by removing a single element from another set in the permutation.
For example, the permutation {1, 2, 3}, {1} is invalid because {1} can not be constructed by removing a single element from {1, 2, 3}.
Is there a known algorithm to find this subset of the power set of a power set? My implementation will be in Python, but the question is language agnostic. Also, I don't actually want the permutations which contain a set with a single element (e.g. {1, 2, 3}, {1, 2}, {1}) because they corresponds to a "dictator" case which is not of interest.
An algorithm to generate all those lists as you describe it could work as follows: For each set in the current list, create a copy, remove one element, add it to the list, and call the algorithm recursively. You also have to make sure not to generate duplicates, which could by done by ensuring that the new list is "smaller" (by length or pairwise comparison of the (sorted) elements) than the previous one.
Here's an implementation in Python, as a generator function, without much optimization. This seems to work pretty well now, generating all the subsets without any duplicates.
def generate_sets(sets, min_num=2):
yield sets
added = set() # new sets we already generated in this iteration
for set_ in sets:
# only if the current set has the right length
if min_num < len(set_) <= len(sets[-1]) + 1:
for x in set_:
# remove each element in turn (frozenset so we can put in into added)
new = set_.difference({x})
# prevent same subset being reachable form multiple sets
frozen = frozenset(new)
if frozen not in added:
added.add(frozen)
# recurse only if current element is "smaller" than last
if (len(new), sorted(new)) < (len(sets[-1]), sorted(sets[-1])):
for result in generate_sets(sets + [new], min_num):
yield result
For generate_sets([{1,2,3}], min_num=2) this generates the following lists:
[{1, 2, 3}]
[{1, 2, 3}, {2, 3}]
[{1, 2, 3}, {2, 3}, {1, 3}]
[{1, 2, 3}, {2, 3}, {1, 3}, {1, 2}]
[{1, 2, 3}, {2, 3}, {1, 2}]
[{1, 2, 3}, {1, 3}]
[{1, 2, 3}, {1, 3}, {1, 2}]
[{1, 2, 3}, {1, 2}]
For generate_sets([{1,2,3}], 1), a total of 45 lists of sets are generated.
However, I fail to see the connection to your previous question: Shouldn't {1, 2, 3}, {1, 2}, {1, 2, 3}, {1, 3}, and {1, 2, 3}, {2, 3} all be considered equivalent?

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}]]

How to create a Mathematica list of fewer columns from larger list of many columns

I have a list "data1":
{{1, 6, 4.5, 1, 141.793, 2.31634, 27.907}, {2, 7, 4.5, 1, 133.702,
2.28725, 26.7442}, {3, 5, 5, 1, 136.546, 2.33522, 25.5814}, {4, 8,
5, 1, 104.694, 2.27871, 24.4186}}
What I would like to do is to create a new table with only the first two columns of each element. So my new table would be:
{{1,6},{2,7},{3,5},{4,8}}
I tried
data1[[All, 1][All, 2]]
and other variations but I am not understanding how to capture the desired fields. Thank you for your help.
Just have a range or list of the indices you want as the second argument, like so:
In[71]:= data[[All, {1, 2}]]
Out[71]= {{1, 6}, {2, 7}, {3, 5}, {4, 8}}

How to handle imported 3D data table for function use?

I imported the 3rd sheet in a xlsx file, which contains 3 columns of data, using
import["e:/temp/15c.xlsx"][[3]]
The data looks like {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}. I wanted to do curve fitting for just one column of data, such as {1, 4, 7} or {2, 5, 8}. I tried
Fit[%[[1, All, All]], {1, x, x^2}, {x}]
but it didn't work. Would anyone please suggest how to get any 1D data out of the 3D table imported? Thank you.
In[1]:= $list = {{1,2,3},{4,5,6},{7,8,9}};
In[2]:= $list[[All, 1]]
Out[2]= {1, 4, 7}
In[3]:= $list[[All, 2]]
Out[3]= {2, 5, 8}
In[4]:= $list[[All, 3]]
Out[4]= {3, 6, 9}
In[5]:= Fit[$list[[All, 2]], {1, x, x^2}, x] // Chop
Out[5]= -1. + 3. x

How to do Tally-like operation on list based on elements' total in Mathematica

For example, I have a list like:
{{1, 2, 3}, {6}, {4, 5}, {1, 6}, {2, 2, 3, 2}, {9}, {7}, {2, 5}}
And I want to get a tallied list based on the total of the lists' elements.
In this case, I want the output to be:
{{6, {{1, 2, 3}, {6}}, {7, {{2, 5}, {1, 6}, {7}}}, {9, {{4, 5}, {2, 2, 3, 2}, {9}}}}}
How to do this conveniently in Mathematica?
Thanks a lot.
Here's my attempt - a little simpler than Yoda's
lst = {{1, 2, 3}, {6}, {4, 5}, {1, 6}, {2, 2, 3, 2}, {9}, {7}, {2, 5}};
{Total#First##, #} & /# GatherBy[lst, Total]
If you don't want repeated elements, then you could use
{Total#First##, Union[#]} & /# GatherBy[lst, Total]
Or if you really wanted a tally-like operation
{Total#First##, Tally[#]} & /# GatherBy[lst, Total]
While I would probably do this just as #Simon did, let us not forget that Reap and Sow can be used as well:
Reap[Sow[#, Total[#]] & /# lst, _, List][[2]]
where lst is the original list. This will be somewhat less efficient than the GatherBy- based code, but also pretty fast. One can speed up the above code about 1.5 times by rewriting it as
Reap[Sow ### Transpose[{lst, Total[lst, {2}]}], _, List][[2]]
in which case it becomes about 1.5 times slower than the code based on GatherBy. Note that the speed difference between the two methods is not very dramatic here, because the list is ragged and therefore not packed, and GatherBy does not have here the speed advantage it normally enjoys for packed arrays.
Don't overlook Tr. This is shorter and faster:
{Tr##, {##}} & ### GatherBy[lst, Tr]

Resources