Sort multi dimensional string array C# - c#-3.0

Here is an example array:
{string[2, 22]}
[0, 0]: "AA"
[0, 1]: "ZZ"
[0, 2]: "AA"
[0, 3]: "ZZ"
[0, 4]: "AA"
[0, 5]: "ZZ"
[0, 6]: "AA"
[0, 7]: "ZZ"
[0, 8]: "AA"
[0, 9]: "ZZ"
[0, 10]: "AA"
[1, 0]: "Ken"
[1, 1]: "Tom"
[1, 2]: "Rom"
[1, 3]: "Som"
[1, 4]: "Sam"
[1, 5]: "Kkk"
[1, 6]: "zzz"
[1, 7]: "Aan"
[1, 8]: "Rome"
[1, 9]: "Sammy"
[1, 10]: "Tanny"
This can have different rows or can also have more columns. But what i am trying to do is sort the array on rows which contain AA & ZZ and sort acending on that.
Is there any easier way to do that? I tried converting this to an enumerable and do .sort that did not work. I also tried few lambda expressions but i am not sure how to find out which row contains all AA and ZZ columns to sort.

Related

How to invocate nested loops one loop at a time?

I want to compare each element against all others like following. The number of variables like a, b, c is dynamic. However, each variable's array size is uniform.
let a = [1, 2, 3]
let b = [3, 4, 5]
let c = [4, 5, 6]
for i in a {
for j in b {
for k in c {
/// comparison
}
}
}
Instead looping from start to finish at once, what would be a way to make each comparison on call? For example:
compare(iteration: 0)
/// compares a[0], b[0], c[0]
compare(iteration: 1)
/// compares a[0], b[0], c[1]
/// all the way to
/// compares a[2], b[2], c[2]
Or it could even be like following:
next()
/// compares a[0], b[0], c[0]
next()
/// compares a[0], b[0], c[1]
almost like an iterator stepping through each cycle dictated by my invocation.
Let the number of arrays be n. And let the number of elements in each array, which is guaranteed the same for all of them, be k.
Then create an array consisting of the integers 0 through k-1, repeated n times. For example, in your case, n is 3, and k is 3, so generate the array
[0, 1, 2, 0, 1, 2, 0, 1, 2]
Now obtain all combinations of n elements of that array. You can do this using the algorithm at https://github.com/apple/swift-algorithms/blob/main/Guides/Combinations.md. Unique the result (by, for example, coercing to a Set and then back to an Array). This will give you a result equivalent, in some order or other, to
[[0, 1, 2], [0, 1, 0], [0, 1, 1], [0, 2, 0], [0, 2, 1], [0, 2, 2], [0, 0, 1], [0, 0, 2], [0, 0, 0], [1, 2, 0], [1, 2, 1], [1, 2, 2], [1, 0, 1], [1, 0, 2], [1, 0, 0], [1, 1, 2], [1, 1, 0], [1, 1, 1], [2, 0, 1], [2, 0, 2], [2, 0, 0], [2, 1, 2], [2, 1, 0], [2, 1, 1], [2, 2, 0], [2, 2, 1], [2, 2, 2]]
You can readily see that those are all 27 possible combinations of the numbers 0, 1, and 2. But that is exactly what you were doing with your for loops! So now, use those subarrays as indexes into each of your original arrays respectively.
So for instance, using my result and your original example, the first subarray [0, 1, 2] yields [1, 4, 6] — the first value from the first array, the second value from the second array, and the third value from the third array. And so on.
In this way you will have generated all possible n-tuples by choosing one value from each of your original arrays, which is the desired result; and we are in no way bound to fixed values of n and k, which was what you wanted to achieve. You will then be able to "compare" the elements of each n-tuple, whatever that may mean to you (you did not say in your question what it means).
In the case of your original values, we will get these n-tuples (expressed as arrays):
[1, 4, 6]
[1, 4, 4]
[1, 4, 5]
[1, 5, 4]
[1, 5, 5]
[1, 5, 6]
[1, 3, 5]
[1, 3, 6]
[1, 3, 4]
[2, 5, 4]
[2, 5, 5]
[2, 5, 6]
[2, 3, 5]
[2, 3, 6]
[2, 3, 4]
[2, 4, 6]
[2, 4, 4]
[2, 4, 5]
[3, 3, 5]
[3, 3, 6]
[3, 3, 4]
[3, 4, 6]
[3, 4, 4]
[3, 4, 5]
[3, 5, 4]
[3, 5, 5]
[3, 5, 6]
Those are precisely the triples of values you are after.
Actual code:
// your original conditions
let a = [1, 2, 3]
let b = [3, 4, 5]
let c = [4, 5, 6]
let originals = [a, b, c]
// The actual solution starts here. Note that I never use any hard
// coded numbers.
let n = originals.count
let k = originals[0].count
var indices = [Int]()
for _ in 0..<n {
for i in 0..<k {
indices.append(i)
}
}
let combos = Array(indices.combinations(ofCount: n))
var combosUniq = [[Int]]()
var combosSet = Set<[Int]>()
for combo in combos {
let success = combosSet.insert(combo)
if success.inserted {
combosUniq.append(combo)
}
}
// And here's how to generate your actual desired values.
for combo in combosUniq {
var tuple = [Int]()
for (outerIndex, innerIndex) in combo.enumerated() {
tuple.append(originals[outerIndex][innerIndex])
}
print(tuple) // in real life, do something useful here
}
}

How to encode column of list for catboost?

I have a dataset where some columns contain lists:
import pandas as pd
df = pd.DataFrame(
{'var1': [1, 2, 3, 1, 2, 3],
'var2': [1, 1, 1, 2, 2, 2],
'var3': [["A", "B", "C"], ["A", "C"], None, ["A", "B"], ["C", "A"], ["D", "A"]]
}
)
var1 var2 var3
0 1 1 [A, B, C]
1 2 1 [A, C]
2 3 1 None
3 1 2 [A, B]
4 2 2 [C, A]
5 3 2 [D, A]
As the values within the lists of var3 can be shuffled and we can't assume any specific order the only way I can think of to prepare the columns for modelling is one-hot encoding. It could be done quite easily:
df["var3"] = df["var3"].apply(lambda x: [str(x)] if type(x) is not list else x)
mlb = MultiLabelBinarizer()
mlb.fit_transform(df["var3"])
resulting in:
array([[1, 1, 1, 0, 0],
[1, 0, 1, 0, 0],
[0, 0, 0, 0, 1],
[1, 1, 0, 0, 0],
[1, 0, 1, 0, 0],
[1, 0, 0, 1, 0]])
However, quoting catboost documentation:
Attention. Do not use one-hot encoding during preprocessing. This
affects both the training speed and the resulting quality.
Therefore, I'd like to ask if there's any other way I could encode this column for modelling with catboost?

Floyd algorithm shortest path

i have written the code below,it works for shortest distance but not for shortest path,
import math
def floyd(dist_mat):
n=len(dist_mat)
p=[[0]*n]*n
for k in range(n):
for i in range(n):
for j in range(n):
if dist_mat[i][j]>dist_mat[i][k]+dist_mat[k][j]:
dist_mat[i][j] = dist_mat[i][k] + dist_mat[k][j]
p[i][j] = k+1
return p
if __name__ == '__main__':
print(floyd([[0,5,9999,9999],
[50,0,15,5],
[30,9999,0,15],
[15,9999,5,0]]))
result of this code is: [[4, 1, 4, 2], [4, 1, 4, 2], [4, 1, 4, 2], [4, 1, 4, 2]]
true result is: [[0, 0, 4, 2], [4, 0, 4, 0], [0, 1, 0, 0], [0, 1, 0, 0]],
I will be happy to receive your ideas about why it works wrong soon

Basic Matlab for loop

A=2;
for x=0:2:4
A=[A, A*x];
end
A
I'd appreciate any help! The for loop condition as well as the 3rd line and how they work together I can't quite piece together
So, here comes the walktrough.
A = 2;
A is an array of length 1, with 2 as the only element.
for x = 0:2:4
Have a look at the Examples section of the for help. You create an "iteration variable" x, which iterates through an array with the values [0, 2, 4]. See also the Examples section of the : operator help.
A = [A, A*x];
Concatenate array A with the value of A*x (multiplying an array with a scalar results in an array of the same length, in which each element is multiplied by the given scalar), and re-assign the result to A. See also the help on Concatenating Matrices.
Initially, A = [2].
For x = 0: A = [[2], [2] * 0], i.e. A = [2, 0].
For x = 2: A = [[2, 0], [2, 0] * 2], i.e. A = [2, 0, 4, 0].
For x = 4: A = [[2, 0, 4, 0], [2, 0, 4, 0] * 4], i.e. A = [2, 0, 4, 0, 8, 0, 16, 0].
end
End of for loop.
A
Output content of A by implicitly calling the display function by omitting the semicolon at the end of the line, see here for explanation.

Assigning to submatrices in python [duplicate]

I want to access a specific row and column restriction of a 2d numpy array.
> x
array([[1, 2, 0],
[3, 4, 0],
[0, 0, 1]])
If I do what seems natural, I just get the diagonal elements of the restricted array.
> x[[0,1], [0,1]]
array([1, 4])
Instead I can do this to read what I want -
> x[[0,1],:][:,[0,1]]
array([[1, 2],
[3, 4]])
..but it doesn't let me write/assign the values.
> x[[0,1],:][:,[0,1]] = np.array([[1,0],[0,1]])
> x
array([[1, 2, 0],
[3, 4, 0],
[0, 0, 1]])
How can I write to a matrix here?
Use np.ix_ to map that grid of elements and then assign -
x[np.ix_([0,1], [0,1])] = np.array([[1,0],[0,1]])
This works too:
x[:2, :2] = np.array([[1, 0], [0, 1]])