Per se number of row in a numpy array - Python - arrays

Imagine that I have a numpy array of 'n' rows by 'm' elements, i.e. shape = (n,m).
If the array is called xrandom and I have a routine like the one shown below and additionally I want to know the row number, what alternatives do I have? (I know that if I had done things differently, I would have the row number, however, I want to know if there is another way to know the row number per se:
for xreg in xrandom:
print(xreg, -line number of xreg-)
I haven't tried anything as I don't know how to.

You can use Python's enumerate:
for row_number, row in enumerate(xrandom):
print(row, row_number)

Related

Can I make an array out of a range of countif functions?

A truncated version of my data is in the form shown in the screenshot below: three columns of 5 unique names. The names appear in any order and in any position but never repeat in a single row.
My goal is to create an array that contains the number of times Adam appears in each row. I can fill down the formula=countif(A2:C2,$I$2) in a new column, or if I write the array manually for each row, it looks like:
={countif(A2:C2,$I$2);countif(A3:C3,$I$2);countif(A4:C4,$I$2);countif(A5:C5,$I$2);countif(A6:C6,$I$2)}
Where cell I2 contains "Adam". Of course, this is not feasible for large data sets.
I know that arrays are effectively cells turned into ranges, but my main issue is that the cell I'm trying to transform already references a range, and I don't know how to tell the software to apply the countif down each row (i.e. I intuitively would like to do something like countif((A2:C2):(A99:C99),"Adam") but understand that's not how spreadsheets work).
My goal is ultimately to perform some operations on the corresponding array but I think I'm comfortable enough with that once I can get the array formula I'm looking for.
try:
=ARRAYFORMULA(IF(A2:A="",,MMULT(IF(A2:C="Adam", 1, 0), {1;1;1})))

Sum Each Row in Array (Google Sheets)

I have a complex formula the produces an Array (10+rows and 10+columns).
For simplicity's sake, let's just say it's =unique(a1:z10)
I'm looking for a formula that can counta() each Row of the array individually. It should basically return a 1-column array that counts the number of values in each row.
Because I will then wrap that in a max() function to see the highest count among them all.
Thanks guys. I hope my question is intelligible.
Let me know if further clarification needed.
The standard way of getting row totals of an m rows by n columns array is
=mmult(<array>,<colvector>)
where <array> is an array of numbers and <colvector> is an array n rows high and one column wide containing all ones.
The standard way of getting <colvector> for a range is
=row(<range>)^0
but this doesn't work for an array because you can only use the row function with a range.
So I think you'd have to generate <colvector> another way - the easiest way is to use Sequence, but unfortunately it means repeating the formula for your <array> to get the column count.
Example
Supposing we choose this as our complex array:
=ArrayFormula(if(mod(sequence(10,10),8),"",sequence(10,10)))
a 10 X 10 array with some spaces in it.
The whole formula to get the row counts would be:
=ArrayFormula(mmult(n(if(mod(sequence(10,10),8),"",sequence(10,10))<>""),
sequence(columns(if(mod(sequence(10,10),7),"",sequence(10,10))))^0))
try:
=MAX(ARRAYFORMULA(MMULT(IFERROR(LEN(B:K)/LEN(B:K), 0), TRANSPOSE(COLUMN(B:K)^0))))
if you want to do it all in one step use:
=MAX(ARRAYFORMULA(MMULT(IFERROR(LEN(B:K)/LEN(B:K), 0),
ROW(INDIRECT("A1:A"&TRANSPOSE(COLUMNS(B:K))))^0)))
where you replace B:K ranges with your formula that outputs the array

Excel: creating an array with n times a constant

I have been looking around for a while but unable to find an answer to my question.
In Excel, what compact formula can I use to create an array made up of a single element repeated n times, where n is an input (potentially hard-coded)?
For example, something that would look like this (the formula below does not work but gives an idea of what I am looking for):
{={"Constant"}*3}
Note: I am not looking for a VBA-based solution.
EDIT Reading #AxelRichter answer, I see I should also indicate that the formulas below assume Constant is a number. If Constant is text, then this solution will not work.
Volatile:
=ROW(INDIRECT("1:" & Repts))/ROW(INDIRECT("1" & ":" & Repts)) * Constant
non-Volatile:
=ROW(INDEX($1:$65535,1,1):INDEX($1:$65535,Repts,1))/ROW(INDEX($1:$65535,1,1):INDEX($1:$65535,Repts,1))*Constant
If
Constant = 14
Repts = 3
then
Result = {14;14;14}
The first part of the formulas create an array of 1's repeated Repts times. Then we multiply that array by Constant to get the desired result.
And after reading #MacroMarc's comment, the following non-volatile formula shouyld also work for numbers:
=(ROW($A$1:INDEX($A:$A,Repts))>0)*Constant
One could concatenate 1:n empty cells to the "Constant" to create a string array having n items "Constant":
"Constant"&INDEX(XFD:XFD,1):INDEX(XFD:XFD,3)
There 3 is n.
Used in Formula
=INDEX("Constant"&INDEX(XFD:XFD,1):INDEX(XFD:XFD,3),0)
Evaluate Formula shows that it works:
Here column XFD is used because in most cases this column will be empty and a column which is guaranteed to be empty is needed for this solution.
If used
"Constant"&T(ROW($A$1:INDEX($A:$A,3)))
=INDEX("Constant"&T(ROW($A$1:INDEX($A:$A,3))),0)
the need of an empty column disappears. The function ROW returns numbers but the T returns an empty string if its parameter is not text. So empty strings will be concatenated for each 1:3 (n).
Thanks to #MacroMarc for the hint.
Try:
REPT("Constant", SEQUENCE(3,1,1,0))
Or, if the reference is to a dynamic array:
REPT("Constant", SEQUENCE(A1#,1,1,0))
The dynamic array spills, and has your constant repeated one time.
Using SEQUENCE with a step of 0 is a much cleaner way to make an array of constants. You can choose whether you want rows or columns (or both!) as well.
=SEQUENCE(Repts,1,Constant,0)
I will generally use a sequence (like Claire (above) said). But if you want to provide an output of text objects, I would do it this way:
=IF(SEQUENCE(A1,A2,1,0),A3)
Where:
A1 has the number of rows
A2 has the number of columns
A3 has the thing you want repeated into an array
The sequence will create a matrix of 1's, which the IF statement will default to the TRUE expression (being the contents of A3).
So, if you wanted a vertical list of 3 items that says "Constant", this would do it:
=IF(SEQUENCE(3,,1,0),"Constant")
If you would prefer it be arranged horizontally instead of vertically, just amend the SEQUENCE function:
=IF(SEQUENCE(,3,1,0),"Constant")

Get Row and Column Totals from 2d Array in Excel

I wanted to know how to get row and column totals from a 2D array in Excel. This is a fairly common thing to do but I couldn't find an answer to it by searching on row and column totals so I thought it would be worth posting it as a question.
Supposing I wanted to find the lowest column total and highest row total in the following array which is in cells A1:D3:-
1 2 3 4
5 6 7 8
9 10 11 12
my initial thoughts were along the lines of
=min(A1:D3*(column(A1:D3)={1,2,3,4}))
but this kind of simple approach doesn't work. I remembered reading that you had to use mmult in some of these situations and have seen advanced formulae using them but couldn't quite remember how. I shall try and answer my own question but other suggestions are more than welcome.
You can do it with MMULT as you mentioned. The following should work with your setup:
Smallest column
=MIN(MMULT({1,1,1},A1:D3))
Largest row:
=MAX(MMULT(A1:D3,{1;1;1;1}))
Note how many 1s in the array - for the rows calc you need a 1 for each column (i.e. 3) and vica versa for columns. Also note the order of the arrays - it won't work the other way around
Yes you have to mmult to deliver either a column array or row array containing the required totals, then use can use MAX, MIN or any other aggregate function to get the value you require.
Column totals
=MIN(MMULT(TRANSPOSE(ROW(A1:D3))^0,A1:D3))
Row Totals
=MAX(MMULT(A1:D3,TRANSPOSE(COLUMN(A1:D3))^0))
So the idea is that you create a single-row array {1,1,1} and multiply it by the 2D array to end up with an array {15,18,21,24} and take the minimum value from it.
Or create a single-column array {1;1;1;1} and multiply the original array by it to end up with an array {10;26;42} from which you get the maximum value.
Remember that mmult works like the matrix multiplication you might have learned at college where for each cell it works across the cells in the corresponding row of the first array and down the cells of the corresponding column in the second array multiplying each pair and adding them to the total. So the number of columns in the first array must always equal the number of rows in the second array.
These are, as #Scott Craner reminds me, array formulae that have to be entered with
Ctrl Shift Enter

aggregate values of one colum by classes in second column using numpy

I've a numpy array with shape N,2 and N>10000. I the first column I have e.g. 6 class values (e.g. 0.0,0.2,0.4,0.6,0.8,1.0) in the second column I have float values. Now I want to calculate the average of the second column for all different classes of the first column resulting in 6 averages one for each class.
Is there a numpy way to do this, to avoid manual loops especially if N is very large?
In pure numpy you would do something like:
unq, idx, cnt = np.unique(arr[:, 0], return_inverse=True,
return_counts=True)
avg = np.bincount(idx, weights=arr[:, 1]) / cnt
I copied the answer from Warren to here, since it solves my problem best and I want to check it as solved:
This is a "groupby/aggregation" operation. The question is this close
to being a duplicate of
getting median of particular rows of array based on index.
... You could also use scipy.ndimage.labeled_comprehension as
suggested there, but you would have to convert the first column to
integers (e.g. idx = (5*data[:, 0]).astype(int)
I did exactly this.

Resources