So I'm trying to get a multidimensional array to work in CoffeeScript. I have tried with standard Python list comprehension notation, that makes the inner bracket a string or something. so I can't do list[0][1] to get 1, I instead get list[0][0] = '1,1' and list[0][1] = ''
[[i, 1] for i in [1]]
Using a class as the storage container, to then grab x and y. Which gives 'undefined undefined', rather then '1 1' for the latter part.
class Position
constructor:(#x,#y) ->
x = [new Position(i,1) for i in [1]]
for i in x
alert i.x + ' ' + i.y#'undefined undefined'
i = new Position(1,1)
alert i.x + ' ' + i.y#'1 1'
Being able to use a list of points is extremely needed and I cannot find a way to make a list of them. I would prefer to use a simple multidimensional array, but I don't know how.
You just need to use parenthesis, (), instead of square brackets, [].
From a REPL:
coffee> ([i, 1] for i in [1])
[ [ 1, 1 ] ]
coffee> [[i, 1] for i in [1]]
[ [ [ 1, 1 ] ] ]
you can see that using the square brackets, as you would in Python, puts the generating expression inside of an extra list.
This is because the parenthesis, () are actually only there in CoffeeScript for when you want to assign the expression to a variable, so:
coffee> a = ([i, 1] for i in [1])
[ [ 1, 1 ] ]
coffee> a[0][1]
1
coffee> b = [i, 1] for i in [1]
[ [ 1, 1 ] ]
coffee> b[0][1]
undefined
Also, see the CoffeeScript Cookbook.
Related
I have an array of 2D, called X and a 1D array for X's classes, what i want to do is slice the same amount of first N percent elements for each class and store inside a new array, for example, in a simple way without doing for loops:
For the following X array which is 2D:
[[0.612515 0.385088 ]
[0.213345 0.174123 ]
[0.432596 0.8714246]
[0.700230 0.730789 ]
[0.455105 0.128509 ]
[0.518423 0.295175 ]
[0.659871 0.320614 ]
[0.459677 0.940614 ]
[0.823733 0.831789 ]
[0.236175 0.10750 ]
[0.379032 0.241121 ]
[0.512535 0.8522193]
Output is 3.
Then, i'd like to store the first 3 index that belongs to class 0 and first 3 elements that belongs to class 0 and maintain the occurence order of the indices, the following output:
First 3 from each class:
[1 0 0 1 0 1]
New_X =
[[0.612515 0.385088 ]
[0.213345 0.174123 ]
[0.432596 0.8714246]
[0.700230 0.730789 ]
[0.455105 0.128509 ]
[0.518423 0.295175 ]]
First, 30% is only 2 elements from each class (even when using np.ceil).
Second, I'll assume both arrays are numpy.array.
Given the 2 arrays, we can find the desired indices using np.where and array y in the following way:
in_ = sorted([x for x in [*np.where(y==0)[0][:np.ceil(0.3*6).astype(int)],*np.where(y==1)[0][:np.ceil(0.3*6).astype(int)]]]) # [0, 1, 2, 3]
Now we can simply slice X like so:
X[in_]
# array([[0.612515 , 0.385088 ],
# [0.213345 , 0.174123 ],
# [0.432596 , 0.8714246],
# [0.70023 , 0.730789 ]])
The definition of X and y are:
X = np.array([[0.612515 , 0.385088 ],
[0.213345 , 0.174123 ],
[0.432596 , 0.8714246],
[0.70023 , 0.730789 ],
[0.455105 , 0.128509 ],
[0.518423 , 0.295175 ],
[0.659871 , 0.320614 ],
[0.459677 , 0.940614 ],
[0.823733 , 0.831789 ],
[0.236175 , 0.1075 ],
[0.379032 , 0.241121 ],
[0.512535 , 0.8522193]])
y = np.array([1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0])
Edit
The following line: np.where(y==0)[0][:np.ceil(0.3*6).astype(int)] doing the following:
np.where(y==0)[0] - returns all the indices where y==0
Since you wanted only the 30%, we slice those indices to get all the values up to 30% - [:np.ceil(0.3*6).astype(int)]
I have got a 3d array (an array of triangles). I would like to get the triangles (2d arrays) containing a given point (1d array).
I went through in1d, where, argwhere but I am still unsuccessfull....
For instance with :
import numpy as np
import numpy.random as rd
t = rd.random_sample((10,3,3))
v0 = np.array([1,2,3])
t[1,2] = v0
t[5,0] = v0
t[8,1] = v0
I would like to get:
array([[[[[ 0.87312 , 0.33411403, 0.56808291],
[ 0.36769417, 0.66884858, 0.99675896],
[ 1. , 2. , 3. ]],
[[ 0.31995867, 0.58351034, 0.38731405],
[ 1. , 2. , 3. ],
[ 0.04435288, 0.96613852, 0.83228402]],
[[ 1. , 2. , 3. ],
[ 0.28647107, 0.95755263, 0.5378722 ],
[ 0.73731078, 0.8777235 , 0.75866665]]]])
to then get the set of v0 adjacent points
{[ 0.87312 , 0.33411403, 0.56808291],
[ 0.36769417, 0.66884858, 0.99675896],
[ 0.31995867, 0.58351034, 0.38731405],
[ 0.04435288, 0.96613852, 0.83228402],
[ 0.28647107, 0.95755263, 0.5378722 ],
[ 0.73731078, 0.8777235 , 0.75866665]}
without looping, the array being quite big.
For instance
In [28]: np.in1d(v0,t[8]).all()
Out[28]: True
works as a test on a line, but I can't get it over the all array.
Thanks for your help.
What I mean is the vectorized equivalent to:
In[54]:[triangle for triangle in t if v0 in triangle ]
Out[54]:
[array([[ 0.87312 , 0.33411403, 0.56808291],
[ 0.36769417, 0.66884858, 0.99675896],
[ 1. , 2. , 3. ]]),
array([[ 0.31995867, 0.58351034, 0.38731405],
[ 1. , 2. , 3. ],
[ 0.04435288, 0.96613852, 0.83228402]]),
array([[ 1. , 2. , 3. ],
[ 0.28647107, 0.95755263, 0.5378722 ],
[ 0.73731078, 0.8777235 , 0.75866665]])]
You can simply do -
t[(t==v0).all(axis=-1).any(axis=-1)]
We are performing ALL and ANY reduction along the last axis with axis=-1 there. First .all(axis=-1) looks for rows exactly matching the array v0 and then the latter .any(axis=-1) looks for ANY match in each of the 2D blocks. This results in a boolean array of the same length as the length of input array. So, we use the boolean array to filter out valid elements off the input array.
i am basically trying to switch around an array of arrays; my initial data are:
array = [
[0,0,0],
[1,1,1]
]
the output should be:
[
[0,1],
[0,1],
[0,1]
]
however what i get is:
[]
i have tried doing the same thing without the loops but when i introduce them it just wont append!
see code here:
array = [
[0,0,0],
[1,1,1]
]
transformedArray = []
#add rows to transformed
for j in range(0, len(array) - 1):
transformedArray.append([])
#for each row
for i in range(0, len(array[0]) - 1):
#for each column
for k in range(0, len(array) - 1):
transformedArray[i].append(array[k][i])
can you help? i have not found any similar issues online so i am guessing i've missed something stupid!
Try nesting your loops:
array = [
[0,0,0],
[1,1,1]
]
transformedArray = [[0,0],[0,0],[0,0]]
# iterate through rows
for i in range(len(array)):
# iterate through columns
for j in range(len(array[0])):
transformedArray[j][i] = array[i][j]
for res in transformedArray:
print(res)
returns:
[0, 1]
[0, 1]
[0, 1]
Edited to Add explanation:
First, lists are defined as in this code above: aList = [ ... ] where an array would be defined as anArray = numpy.array([...]), so to the point of the comments above, this is list processing in the question, not true python array process. Next, elements are being added to the list by index, so there has to be a place to put them. I handled that by creating a list with 3 elements already in place. The original post would only create the first 2 rows and then have an index failure when the 3rd row is to be created. The nested for loops then iterate through the embedded lists.
You could do it by mapping a sequence of index-access operations over all the arrays:
for i in range( len( array[0] ) ):
transformedArray.append( map( lambda x: x[i], array ) )
I had to update an array, and I used += and << in different runs of code inside a block passed to Array#each_with_object:
Code 1
(1..5).each_with_object([]) do |i, a|
puts a.inspect
a += [i]
end
Output:
[]
[]
[]
[]
[]
Code 2
(1..5).each_with_object([]) do |i, a|
puts a.inspect
a << [i]
end
Output:
[]
[1]
[1,2]
[1,2,3]
[1,2,3,4]
The += operator does not update the original array. Why? What am I missing here?
In each_with_object, the so-called memo object is common among the iterations. You need to modify that object in order to do something meaningful. The += operator is syntax sugar for + and assignment, which does not modify the receiver, hence the iteration has no effect. If you use methods like << or push, then it will have effect.
On the other hand, in inject, the so-called memo object is the return value of the block, and you don't need to modify the object, but you need to return the value you want for the next iteration.
It is clear to me that += operator is not updating the original array. Why?
Because the documentation says so (emphasis mine):
ary + other_ary → new_ary
Concatenation — Returns a new array built by concatenating the two arrays together to produce a third array.
[ 1, 2, 3 ] + [ 4, 5 ] #=> [ 1, 2, 3, 4, 5 ]
a = [ "a", "b", "c" ]
c = a + [ "d", "e", "f" ]
c #=> [ "a", "b", "c", "d", "e", "f" ]
a #=> [ "a", "b", "c" ]
Note that
x += y
is the same as
x = x + y
This means that it produces a new array. As a consequence, repeated use of += on arrays can be quite inefficient.
See also #concat.
Compare to <<
ary << obj → ary
Append—Pushes the given object on to the end of this array. This expression returns the array itself, so several appends may be chained together.
[ 1, 2 ] << "c" << "d" << [ 3, 4 ]
#=> [ 1, 2, "c", "d", [ 3, 4 ] ]
The documentation of Array#+ clearly says that a new array is returned (no less than four times, actually). This is consistent with other uses of the + method in Ruby, e.g. Bignum#+, Fixnum#+, Complex#+, Rational#+, Float#+, Time#+, String#+, BigDecimal#+, Date#+, Matrix#+, Vector#+, Pathname#+, Set#+, and URI::Generic#+.
I'm trying to push data to a REST api using powershell.
http://influxdb.com/docs/v0.8/api/reading_and_writing_data.html
The server expects data like so:
[
{
"name" : "hd_used",
"columns" : ["value", "host", "mount"],
"points" : [
[23.2, "serverA", "mnt"]
]
}
]
However, I"m only able to make a json object that looks like this (notice the extra quotes):
[
{
"name" : "hd_used",
"columns" : ["value", "host", "mount"],
"points" : [
"[23.2, "serverA", "mnt"]"
]
}
]
How can I construct the data into an array of arrays without wrapping the nested array in quotes?
This works, but it isn't a nested array
$influxdata = [ordered]#{}
$influxdata.name = $hd_used
$influxdata.columns = #("value", "host", "mount")
$influxdata.points = #()
$influxdata.points += #("23.2", "serverA", "mnt")
$influxdatajson = $influxdata | ConvertTo-Json -Depth 2
This works but the inner array is actually a string.
$influxdata = [ordered]#{}
$influxdata.name = $hd_used
$influxdata.columns = #("value", "host", "mount")
$influxdata.points = #()
$influxdata.points += #('["23.2", "serverA", "mnt"]')
$influxdatajson = $influxdata | ConvertTo-Json -Depth 2
With $PSVersion.$PSVersion equal to 3.0 and your exact input I get the following when I print the $influxdatajson variable:
{
"name": "hd_used",
"columns": [
"value",
"host",
"mount"
],
"points": [
"23.2",
"serverA",
"mnt"
]
}
Which clearly isn't what you want but isn't what you said you got either.
The reason that that is the output we get is because your attempt to add the array to the existing array didn't work the way you expect because of powershell's annoying tendency to unroll arrays (I think).
If you work around that oddity by using this syntax instead:
$influxdata.points += ,#("23.2", "serverA", "mnt")
(the leading , forces an array context so that outer array gets unrolled instead of the array you are trying to add)
then I get the following output from $influxdatajson:
{
"name": "hd_used",
"columns": [
"value",
"host",
"mount"
],
"points": [
[
"23.2",
"serverA",
"mnt"
]
]
}
To complement Etan Reisner's helpful answer (whose of use unary , to create a nested array solves the problem):
PowerShell's hashtable literals are quite flexible with respect to incorporating variable references, expression, and commands, which makes for a more readable solution:
,, [ordered] #{
name = 'hd_used'
columns = 'value', 'host', 'mount'
points = , (23.2, 'serverA', 'mnt')
} | ConvertTo-Json -Depth 3
This yields:
[
{
"name": "hd_used",
"columns": [
"value",
"host",
"mount"
],
"points": [
[
23.2,
"serverA",
"mnt"
]
]
}
]
Note how the array-construction operator (,) is applied twice at the beginning of the pipeline (before [ordered]):
first to turn the ordered hashtable into a (single-item) array,
and the 2nd time to wrap that array in an outer array.
Sending the result through the pipeline makes PowerShell unwrap any collection, i.e., enumerate the collection items and send them one by one, which in this case strips away the outer array, leaving ConvertTo-Json to process the inner array, as desired.
Note that passing an array adds a level to the hierarchy, which is why the -Depth value was increased to 3 above.
Caveat: Any property whose hierarchy level is deeper than -Depth is stringified (evaluated as if placed inside "$(...)"), which in the case of an array would simply join the array elements with a space; e.g., array 23.2, 'serverA', 'mnt' would turn to a single string with literal contents 23.2 serverA mnt.
Note how the arrays above do not use syntax #(...), because it is generally not necessary to construct arrays and is actually less efficient: simply ,-enumerate the elements, and, if necessary, enclose in (...) for precedence (although #() is syntactically convenient for creating an empty array).
+ with an array as the LHS doesn't so much unwrap (unroll) its RHS, but concatenates arrays, or, to put it differently, allows you to append multiple individual items; e.g.:
$a = 1, 2
$a += 3, 4 # add elements 3 and 4 to array 1, 2 to form array 1, 2, 3, 4
Note that the use of += actually creates a new array behind the scenes, given that arrays aren't resizable.
Just to add my two pence worth. Its is worth noting that everytime you touch an array and you know is a single item array, you must use the appropriate comma syntax. This is not well highlighted in articles I found on the subject.
Take this example case I wrote for a Pester test case:
A lesson about single item arrays, every time you touch a single item array, you must use the comma op. It is not a case of set it and forget it:
Mock get-AnswerAdvancedFn -ModuleName Elizium.Loopz {
$pairs = #(, #('Author', 'Douglas Madcap Adams'));
$first = $pairs[0];
Write-Host "=== SINGLE-ITEM: pairs.count: $($pairs.Count), first.count: $($first.Count)"
([PSCustomObject]#{ Pairs = $pairs })
}
The above won't work, because of the fault assigning $pairs to Pairs even though we've used the correct syntax setting $pairs to #(, #('Author', 'Douglas Madcap Adams'))
The following fixes this issue; everytime you touch the single item array, you must use the comma syntax, otherwise you give PowerShell another chance to flatten your array:
Mock get-AnswerAdvancedFn -ModuleName Elizium.Loopz {
$pairs = #(, #('Author', 'Douglas Madcap Adams'));
$first = $pairs[0];
Write-Host "=== SINGLE-ITEM: pairs.count: $($pairs.Count), first.count: $($first.Count)"
([PSCustomObject]#{ Pairs = , $pairs })
}
My test code ended up being this:
Mock get-AnswerAdvancedFn -ModuleName Elizium.Loopz {
([PSCustomObject]#{ Pairs = , #(, #('Author', 'Douglas Madcap Adams')) })
}
Note, we had to use the comma op twice and both of those are necessary