Mathematica Asked by RMMA on June 8, 2021
I have a list which looks like this: l={{1,0,3,4},{0,2},{0,0,1,3},{1,2,0}}
. Now I would like to count how many 0s the sublists contain in the first, second,… slot.
The result for this example should be: {2,2,1,0}
. Since the sublists do not have the same length MapThread
does not work.
I would be grateful for a solution.
You can use Flatten
to transpose a ragged array:
list = {{1, 0, 3, 4}, {0, 2}, {0, 0, 1, 3}, {1, 2, 0}}
Count[#, 0] & /@ Flatten[list, {{2}, {1}}]
(* {2, 2, 1, 0} *)
Edit
Step one is to transpose your list but in this case the list is ragged so Tranpose
doesn't work:
Transpose[list]
However Flatten
can transpose a ragged list (type Flatten
in the documentation center and then go to "Applications"):
Flatten[list, {{2}, {1}}]
(* {{1, 0, 0, 1}, {0, 2, 0, 2}, {3, 1, 0}, {4, 3}} *)
Now that the list is transposed you can count the number of zeros, this is done by mapping the transposed list onto Count
Map[Count[#, 0] &, Flatten[list, {{2}, {1}}]]
Correct answer by Mike Honeychurch on June 8, 2021
Say you have
l = {{1, 0, 3, 4}, {0, 2}, {0, 0, 1, 3}, {1, 2, 0}, {1, 1, 1, 1, 0}};
There is a bit different approach to your function:
Sort@Tally@Position[l, 0][[All, 2]]
{{1, 2}, {2, 2}, {3, 1}, {5, 1}}
which is compressed from of your information. It gives you slot index and number of 0s there. If slot has no zeros it is not mentioned. If you have a lot of zero-less slots such format is much shorter.
Grid[{{"slot", "zeros"}}~Join~%, Frame -> All]
And here is clunky exercise in padding arrays (with help of Mike's comment) :
zcount[l_List] := With[{m = Max[Length /@ l]}, (Count[#, 0] & /@
Transpose[PadRight[#, m, None] & /@ l])]
The usage:
zcount[l]
{2, 2, 1, 0, 1}
Answered by Vitaliy Kaurov on June 8, 2021
Since
and
the following variations also work:
list = {{1, 0, 3, 4}, {0, 2}, {0, 0, 1, 3}, {1, 2, 0}, {1, 1, 1, 1, 0}};
Count[#, 0] & /@ Transpose@PadRight[list, Automatic, "x"]
(* or *)
Tr /@ Transpose@PadRight[Map[Boole[# == 0] &, list, {-1}]]
(* or *)
Plus @@ PadRight[Boole[# == 0] & /@ # & /@ list]
(* => {2,2,1,0,1} *)
EDIT: Few more ways:
Rest@Total@BinCounts@Position[list, 0]
Count[Position[list, 0], {_, #}] & /@ Range@Length@list
Length@Position[Position[list, 0], {_, #}] & /@ Range@Length@list
Answered by kglr on June 8, 2021
I propose this:
Total @ PadRight[1 - Unitize[list]]
Answered by Simon Woods on June 8, 2021
Since MapThread
accepts a level specification, I think our ragged MapThread function should too.
raggedMapThread[f_, expr_, level_Integer: 1] :=
Apply[f, Flatten[expr, List /@ Range[2, level + 1]], {level}]
To solve the specific case posed in the question:
raggedMapThread[
Count[{##}, 0] &,
{{1, 0, 3, 4}, {0, 2}, {0, 0, 1, 3}, {1, 2, 0}}
]
{2, 2, 1, 0}
Extended to level 2 with an example function test
:
a = {{{67, 47}, {5, 99}, {70, 44}, {9}},
{{75, 70}, {61}, {16, 23}, {50, 80}},
{{87, 11}, {10}, {29, 16}}};
PadRight[a, Automatic, ""] // MatrixForm (* for illustration *)
raggedMapThread[test, a, 2] // MatrixForm
Answered by Mr.Wizard on June 8, 2021
Here's a solution for when you have one list and one scalar. Perhaps it can be adapted to your needs -- maybe I'll come back and edit it tailored to your use-case a little more later, but I think you'll get the point.
EDIT: Just saw that this post was from 2012; maybe I won't rush on tailoring it to your needs, but this post came up near the top in my Google search, so maybe somebody else will get some use out of these...
Method 1
Inner[MyFunction, {d}, {{a, b, c}}]
Inner[MyFunction, {{a, b, c}}[Transpose], {d}, Reverse]
Output (they're equivalent) [leaving it to the reader to do it in the opposite order]:
{MyFunction[d, a], MyFunction[d, b], MyFunction[d, c]}
Method 2 - might be more adaptable for you:
Outer[MyFunction, {a, b, c}, {d}]
Output:
{{MyFunction[a, d]}, {MyFunction[b, d]}, {MyFunction[c, d]}}
Method 3
Distribute[MyFunction[{a, b, c}, d], List]
Output:
{{MyFunction[a, d]}, {MyFunction[b, d]}, {MyFunction[c, d]}}
Update -- GENERAL-CASE SOLUTIONS:
DistributeOp[distributeOver_] := Function[expr, Distribute[expr, distributeOver]]
EnsureList[expr_] := Flatten[{expr}, 1]
MapThreadRagged1[func_, a_, b_] := Inner[func, {EnsureList[a]}[Transpose], {EnsureList[b]}]
MapThreadRagged2[func_, a_, b_] := Outer[func, EnsureList[a], EnsureList[b]]
MapThreadRagged3[func_, a_, b_] := DistributeOp[List]@func[EnsureList[a], EnsureList[b]]
Output:
MapThreadRagged1[f, {a, b}, {c, d}]
MapThreadRagged1[f, a, b]
MapThreadRagged2[f, {a, b}, {c, d}]
MapThreadRagged2[f, a, b]
MapThreadRagged3[f, {a, b}, {c, d}]
MapThreadRagged3[f, a, b]
{{f[a, c], f[a, d]}, {f[b, c], f[b, d]}}
{{f[a, b]}}
{{f[a, c], f[a, d]}, {f[b, c], f[b, d]}}
{{f[a, b]}}
{f[a, c], f[a, d], f[b, c], f[b, d]}
{f[a, b]}
Answered by Sean on June 8, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP