Related
From:
arr1 = np.array([ [1, 2, 3], [4, 5, 6], [7, 8, 9] ])
To:
arr1 = np.array([ [0, 1, 2, 3], [0, 4, 5, 6], [0, 7, 8, 9] ])
You can try something like this with numpy.full:
x = 0
new = np.full((arr1.shape[0], arr1.shape[1] + 1), x)
new[:, 1:] = arr1
Output
new
array([[0, 1, 2, 3],
[0, 4, 5, 6],
[0, 7, 8, 9]])
Note that you can assign any value to x.
Your (3,3) 2d array:
In [100]: arr1 = np.array([ [1, 2, 3], [4, 5, 6], [7, 8, 9] ])
In [101]: arr1
Out[101]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
A new (3,4) array:
In [102]: np.concatenate((np.zeros((3,1),int),arr1), axis=1)
Out[102]:
array([[0, 1, 2, 3],
[0, 4, 5, 6],
[0, 7, 8, 9]])
Any other (3,1) array (or even a (3,n)) could be added "at the start" like this.
I think I'm missing something obvious. Consider the following code:
import numpy as np
a = np.array([[ 0, 2, 0, 5, 4, 6, 2, 4],
[ 3, 4, 0, 1, 0, 7, 4, 6],
[ 2, 6, 3, 5, 2, 5, 5, 8],
[ 0, 1, 0, 8, 0, 5, 8, 10],
[ 7, 9, 2, 7, 0, 6, 7, 2],
[ 0, 1, 4, 9, 0, 7, 9, 9],
[ 0, 6, 7, 5, 6, 2, 4, 13],
[ 0, 1, 1, 4, 1, 3, 2, 3]]
# isolate columns 2,3,6,7
mask = [False,False, True, True,False,False, True, True]
b = a[:,mask]
# determine rows of b having unique elements
s = np.sort(b, axis=1)
c = b[~(s[:,:-1] == s[:,1:]).any(1)]
c looks like:
c = [[ 0, 5, 2, 4],
[ 0, 1, 4, 6],
[ 7, 5, 4, 13],
[ 1, 4, 2, 3]]
QUESTION: How do I 'recover' the rows of a that gave rise to the rows of c?
The output should be like:
d = [[ 0, 2, 0, 5, 4, 6, 2, 4],
[ 3, 4, 0, 1, 0, 7, 4, 6],
[ 0, 6, 7, 5, 6, 2, 4, 13],
[ 0, 1, 1, 4, 1, 3, 2, 3]]
I would like the following hash output:
{ 0 => [0,1,2], 1 => [0,1,2], 2 => [0,1,2],
3 => [3,4,5], 4 => [3,4,5], 5 => [3,4,5],
6 => [6,7,8], 7 => [6,7,8], 8 => [6,7,8]
}
Intuitively I can just hard code these values in, but I am struggle to figure out how I can dynamically assign each hash key to the appropriate array value.. For instance perhaps creating a 9.times loop?
{ 0 => (0..2).to_a, 1 => (0..2).to_a, 2 => (0..2).to_a,
3 => (3..5).to_a, 4 => (3..5).to_a, 5 => (3..5).to_a,
6 => (6..8).to_a, 7 => (6..8).to_a, 8 => (6..8).to_a
}
Thanks for any guidance
With a dynamic upper bound:
count, split = 9, 3
0.upto(count - 1).map do |i|
[i, [*(i / split * split)...(i / split) * split + split]]
end.to_h
Using modulo operations (%) you can calculate the values of the subarrays:
(0..8).map { |i| [i, (i - i%3 .. i - i%3 + 2).to_a] }.to_h
# => {0=>[0, 1, 2], 1=>[0, 1, 2], 2=>[0, 1, 2], 3=>[3, 4, 5], 4=>[3, 4, 5], 5=>[3, 4, 5], 6=>[6, 7, 8], 7=>[6, 7, 8], 8=>[6, 7, 8]}
Maybe something like this:
[0..2, 3..5, 6..8].each.with_object({}) do |range, result|
range.each do |ind|
result[ind] = range.to_a
end
end
dummy_data = {}
(0..8).to_a.each_slice(3).map{ |m| m.each{|v| dummy_data[v] = m }}
it generates expected dummy data
dummy_data
=> {0=>[0, 1, 2], 1=>[0, 1, 2], 2=>[0, 1, 2], 3=>[3, 4, 5], 4=>[3, 4, 5], 5=>[3, 4, 5], 6=>[6, 7, 8], 7=>[6, 7, 8], 8=>[6, 7, 8]}
def make_da_hash(n)
a = (0..n*n-1).to_a
a.zip(a.each_slice(n).flat_map { |e| [e]*n }).to_h
end
make_da_hash(3)
#=> {0=>[0, 1, 2], 1=>[0, 1, 2], 2=>[0, 1, 2],
# 3=>[3, 4, 5], 4=>[3, 4, 5], 5=>[3, 4, 5],
# 6=>[6, 7, 8], 7=>[6, 7, 8], 8=>[6, 7, 8]}
make_da_hash(4)
#=> {0=>[0, 1, 2, 3], 1=>[0, 1, 2, 3], 2=>[0, 1, 2, 3], 3=>[0, 1, 2, 3],
# 4=>[4, 5, 6, 7], 5=>[4, 5, 6, 7], 6=>[4, 5, 6, 7], 7=>[4, 5, 6, 7],
# 8=>[8, 9, 10, 11], 9=>[8, 9, 10, 11], 10=>[8, 9, 10, 11],
# 11=>[8, 9, 10, 11], 12=>[12, 13, 14, 15], 13=>[12, 13, 14, 15],
# 14=>[12, 13, 14, 15], 15=>[12, 13, 14, 15]}
{}.merge(*Array.new(3){|i| (0..8).group_by{|n| n / 3 * 3 + i}})
Output:
{
0=>[0, 1, 2],
3=>[3, 4, 5],
6=>[6, 7, 8],
1=>[0, 1, 2],
4=>[3, 4, 5],
7=>[6, 7, 8],
2=>[0, 1, 2],
5=>[3, 4, 5],
8=>[6, 7, 8]
}
I just have a question,
I have been building alexa skill. (the Concept is Randomize Positivity)
but somehow it keep returning the same sentence....
this is my code...
` for (var j = 0; j < index; j++){
var rand = Math.floor(Math.random() * index);
index -= 1;
var temp = indexList[index];
indexList[index] = indexList[rand];
indexList[rand] = temp;
}`// I also swap the words so It would sure not to return the same but somehow it happens..
and the index is about 15 strings for now...
my Question is how do I make it random as possible?
You're just trying to shuffle an array, right? See the Fisher-Yates shuffle. You're already almost doing the same thing.
I tried this and it worked fine.
var indexList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
var rand;
var temp;
for (let i = 0; i < indexList.length; i++) {
rand = Math.floor(Math.random() * (i + 1));
temp = indexList[i];
indexList[i] = indexList[rand];
indexList[rand] = temp;
console.log(indexList);
}
It printed the following, showing that it is shuffling the array more and more each step:
> Array [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
> Array [2, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
> Array [3, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
> Array [4, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
> Array [4, 1, 5, 3, 2, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
> Array [4, 6, 5, 3, 2, 1, 7, 8, 9, 10, 11, 12, 13, 14, 15]
> Array [4, 6, 5, 3, 2, 1, 7, 8, 9, 10, 11, 12, 13, 14, 15]
> Array [4, 6, 5, 3, 2, 8, 7, 1, 9, 10, 11, 12, 13, 14, 15]
> Array [4, 6, 5, 3, 2, 8, 9, 1, 7, 10, 11, 12, 13, 14, 15]
> Array [4, 6, 5, 3, 2, 8, 9, 1, 10, 7, 11, 12, 13, 14, 15]
> Array [4, 6, 5, 3, 2, 8, 9, 1, 10, 7, 11, 12, 13, 14, 15]
> Array [4, 6, 5, 3, 2, 8, 9, 1, 12, 7, 11, 10, 13, 14, 15]
> Array [4, 6, 5, 3, 2, 8, 9, 1, 12, 7, 11, 10, 13, 14, 15]
> Array [4, 6, 14, 3, 2, 8, 9, 1, 12, 7, 11, 10, 13, 5, 15]
> Array [4, 6, 15, 3, 2, 8, 9, 1, 12, 7, 11, 10, 13, 5, 14]
Is there any method to split an array like this?
[1, 2, 3, 4, 5, 6, 7, 8, 9].split(3, 4, 2)
#=> [[1, 2, 3],[4, 5, 6, 7],[8, 9]]
Immutable version with λ:
▶ splitter = ->(array, *parts) do
parts.reduce([[], 0]) do |acc, i|
right = acc.last + i
[acc.first << (acc.last...right), right]
end.first.map { |r| array[r] }
end
#⇒ #<Proc:0x0055ae3d9ae7c8#(pry):18 (lambda)>
▶ splitter.((1..9).to_a, 3, 4, 2)
#⇒ [[1, 2, 3], [4, 5, 6, 7], [8, 9]]
No, there is none, but you can easily write one yourself.
class Array
def in_groups_of_n(*sizes)
sizes.map(&method(:shift))
end
end
Example:
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
arr.in_groups_of_n(3, 4, 2)
# => [[1, 2, 3], [4, 5, 6, 7], [8, 9]]
Demonstration
In case you want a none-destructive version, you can use a dup method:
class Array
def in_groups_of_n(*sizes)
duplicate = dup
sizes.map { |size| duplicate.shift(size) }
end
end
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
arr.in_groups_of_n(3,4,2)
# => [[1, 2, 3], [4, 5, 6, 7], [8, 9]
arr
# => [1, 2, 3, 4, 5, 6, 7, 8, 9]
Demonstration
Here's a naive Array implementation:
class Array
def multi_split(*sizes)
r = []
e = self.each
sizes.each do |size|
t = []
size.times do
t << e.next
end
r << t
end
r
end
end
p [1, 2, 3, 4, 5, 6, 7, 8, 9].multi_split(3, 4, 2)
# [[1, 2, 3], [4, 5, 6, 7], [8, 9]]
#Stefan mentioned it might make sense to implement it on Enumerable:
module Enumerable
def multi_split(*sizes)
Enumerator.new do |yielder|
e = self.each
sizes.each do |size|
yielder << Array.new(size){ e.next }
end
end
end
end
p [1, 2, 3, 4, 5, 6, 7, 8, 9].multi_split(3, 4, 2).to_a
# [[1, 2, 3], [4, 5, 6, 7], [8, 9]]
Another option (lossless in event the splits are not equal to the array size
def split_at(arr,splits)
rest = arr.last(arr.size - splits.reduce(:+))
enum = arr.to_enum
splits.map do |n|
n.times.map { enum.next }
end.concat(rest.empty? ? [] : [rest])
end
Then called as
split_at (1..9), [3,4,2]
#=> [[1, 2, 3], [4, 5, 6, 7], [8, 9]]
split_at (1..22), [3,4,2]
#=> [[1, 2, 3], [4, 5, 6, 7], [8, 9], [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]]
Example
class Array
def split_by_number(*sizes)
sizes.each_with_object([]) { |n,a| a << [a.empty? ? 0 : a.last.sum, n] }.
map { |start, nbr| self[start, nbr] }
end
end
[1, 2, 3, 4, 5, 6, 7, 8, 9].split_by_number 3, 4, 2
#=> [[1, 2, 3], [4, 5, 6, 7], [8, 9]]
Note that
[3, 4, 2].each_with_object([]) { |n,a| a << [a.empty? ? 0 : a.last.sum, n] }
#=> [[0, 3], [3, 4], [7, 2]]