I was trying to display intrabar close values inside the current chart's bar(15 min). So there are three values. But the values comes as tuple.
I cannot separate the tuples to three values. I have tried the below code as well as using for loop(which I am not familiar with),
[fir, sec, thi] = request.security_lower_tf(syminfo.tickerid, "5", close)
var table top_boxes = table.new(position.bottom_center, 6, 2)
table.cell(top_boxes, 0, 0, text=str.tostring(a), bgcolor=color.new(color.blue, 0), text_color=color.white, width=4, height=8)
table.cell(top_boxes, 1, 0, text=str.tostring(b), bgcolor=color.new(color.red, 0), text_color=color.white, width=4, height=8)
table.cell(top_boxes, 1, 0, text=str.tostring(c), bgcolor=color.new(color.yellow, 0), text_color=color.white, width=4, height=8)
Can someone help me to separate the values in the array and display them.
Since you only request close price, request.security_lower_tf() function returns an array with 3 elements.
You can get the value of each element using array.get():
close_5 = request.security_lower_tf(syminfo.tickerid, "5", close)
var table top_boxes = table.new(position.bottom_center, 6, 2)
if barstate.islast
table.cell(top_boxes, 0, 0, text=str.tostring(array.get(close_5, 0)), bgcolor=color.new(color.blue, 0), text_color=color.white, width=4, height=8)
table.cell(top_boxes, 1, 0, text=str.tostring(array.get(close_5, 1)), bgcolor=color.new(color.red, 0), text_color=color.white, width=4, height=8)
table.cell(top_boxes, 2, 0, text=str.tostring(array.get(close_5, 2)), bgcolor=color.new(color.yellow, 0), text_color=color.white, width=4, height=8)
In some cases, there will be missing some 5 min bars in order to return 3 elements into that array. You can write a "safer" code using a for loop:
//#version=5
indicator("request 5 min timeframe", overlay = true)
close_5 = request.security_lower_tf(syminfo.tickerid, "5", close)
var table top_boxes = table.new(position.bottom_center, 6, 2)
if barstate.islast
color[] cell_bg_color = array.from(color.blue, color.red, color.yellow)
for [index, price] in close_5
table.cell(top_boxes, index, 0, text=str.tostring(price), bgcolor=array.get(cell_bg_color, index), text_color=color.white)
I have two arrays and the indices of these arrays are related. So x[0] is related to y[0], so they need to stay organized. I have binned the x array into two bins as shown in the code below.
x = [1,4,7,0,5]
y = [.1,.7,.6,.8,.3]
binx = [0,4,9]
index = np.digitize(x,binx)
Giving me the following:
In [1]: index
Out[1]: array([1, 2, 2, 1, 2])
So far so good. (I think)
The y array is a parameter telling me how well measured the x data point is, so .9 is better than .2, so I'm using the next code to sort out the best of the y array:
y.sort()
ysorted = y[int(len(y) * .5):]
which gives me:
In [2]: ysorted
Out[2]: [0.6, 0.7, 0.8]
giving me the last 50% of the array. Again, this is what I want.
My question is how do I combine these two operations? From each bin, I need to get the best 50% and put these new values into a new x and new y array. Again, keeping the indices of each array organized. Or is there an easier way to do this? I hope this makes sense.
Many numpy functions have arg... variants that don't operate "by value" but rather "by index". In your case argsort does what you want:
order = np.argsort(y)
# order is an array of indices such that
# y[order] is sorted
top50 = order[len(order) // 2 :]
top50x = x[top50]
# now top50x are the x corresponding 1-to-1 to the 50% best y
You should make a list of pairs from your x and y lists
It can be achieved with the zip function:
x = [1,4,7,0,5]
y = [.1,.7,.6,.8,.3]
values = zip(x, y)
values
[(1, 0.1), (4, 0.7), (7, 0.6), (0, 0.8), (5, 0.3)]
To sort such a list of pairs by a specific element of each pair you may use the sort's key parameter:
values.sort(key=lambda pair: pair[1])
[(1, 0.1), (5, 0.3), (7, 0.6), (4, 0.7), (0, 0.8)]
Then you may do whatever you want with this sorted list of pairs.
I am trying to iterate over two 2D arrays. But, somehow iterator skips every alternate element in row. 'bimg' and 'dist'size is 20x12. But, for every row, it iterates over 0, 2, 4 ... columns instead of 0,1,2,3,4, ...
Code snippet:
it = np.nditer([bimg, dist],
op_flags=[['readonly'],['readonly']],
flags = ['multi_index', 'multi_index'])
rows, cols = bimg.shape
print "bimg dimensions: ", bimg.shape
print "dist dimensions: ", dist.shape
for cur_b, cur_d in it:
print "MULTI_IDX = ", it.multi_index
Output:
bimg dimensions: (20L, 12L)
dist dimensions: (20L, 12L)
MULTI_IDX = (0, 0)
MULTI_IDX = (0, 2)
MULTI_IDX = (0, 4)
MULTI_IDX = (0, 6)
MULTI_IDX = (0, 8)
MULTI_IDX = (0, 10)
MULTI_IDX = (1, 0)
MULTI_IDX = (1, 2)
To understand this issue, if I create array on python prompt and try to iterate over it works correctly:
Correctly working code:
x = np.array(np.arange(240))
x = x.reshape(20,12)
y = np.array(np.arange(240))
y = y + 100
y = y.reshape(20,12)
it = np.nditer([x,y],
op_flags = [['readonly'],['readonly']],
flags= ['multi_index', 'multi_index'])
for a, b in it:
print it.multi_index
Output:
MULTI_INDEX = (0, 0)
MULTI_INDEX = (0, 1)
MULTI_INDEX = (0, 2)
MULTI_INDEX = (0, 3)
MULTI_INDEX = (0, 4)
MULTI_INDEX = (0, 5)
I don't see the difference. When I define:
bimg = x
dist = y
I get the same iteration with both clips.
flags only needs 'multi_index' once. It applies to the whole iteration, op_flags to each array:
flags= ['multi_index']
While the documentation describes nditer as efficient multi-dimensional iterator object, it doesn't seem to help much with speed in Python code. In C or Cython is streamlines the whole process of iterating over multiple array.
Here's another way of generating the multi_index. Actually it's not so different. Internally ndindex constructs a dummy array of the desired shape, and returns an iterable. Look at its code.
for i, j in np.ndindex(bimg.shape):
print i,j
According the tutorial Iterating over Array page, the correct way to use multi_index is with the c style iterator:
while not it.finished:
print it.multi_index
it.iternext()
I'm not sure why. What are the dtypes of bimg and dist?
I have a 2D grid that has some obstacles in it.
[x][x][ ]
[ ][ ][ ]
[ ][ ][x]
I want to be able to find all the largest spaces of "open" grid cells.
[x][x][ ] [x][x][ ]
[1][1][ ] [2][2][2]
[1][1][x] and [ ][ ][x]
I saw the question here which is similar; however, the data I have access to is not a 2D array of values. I have a list of only the open/available indices, and this is stored in a single-dimensional array. Using the above example, my data looks like this:
[0,2]
[1,0]
[1,1]
[1,2]
[2,0]
[2,1]
I could translate it to a 2-D array, but I don't want to have to loop over all the items again to do that. I have a feeling there is some really simple solution to this, but I can't seem to find it.
Is there a way to find all the largest rectangles by only examining a list of the open indices?
EDIT
I just decided to change the array of open indices into a 2D array representing the entire grid, then use the algorithm I linked to. This works efficiently enough for my initial tests; however, I am interested to read about other possible solutions, should I need to alter my implementation for performance or space concerns.
Of course.
To find a rectangle:
Start with any free cell. Assume this is going to be the upper-left corner.
See if it can be extended horizontally.
See if it can be extended vertically.
Backtrack.
I'll ellaborate on this later, but thought this could give you a jump-start.
The list of available coordinates is sorted.
So have a global, upto-now maximum rectangle, as list too.
Do a list walk, and for every item call a function with the sublist starting at the item. To find the largest rectangle starting top-left with that item.
public List<Coord> getMaxRectangle(List<Coord> openCoords) {
List<Coord> currentMaxRectangle = null;
for (int i = 0; i < openCoords.size(); ++i) {
// Handle all rectangles starting here:
currentMaxRectangle = maxRectangleStartingAt(i, currentMaxRectangle);
}
return currentMaxRectangle;
}
public List<Coord> maxRectangleStartingAt(int i, List<Coord> openCoords) {
// Now the interesting part:
// Take the maximal width list first: standing for all widths 1, ... max width.
List<Coord> rect = new ArrayList<>();
for (int j = i; j < openCoords.size()
&& openCoords.get(j).y == openCoords.get(i).y
&& openCoords.get(j).x - openCoords.get(i).x == j - i;
++j) {
rect.add(openCoords.get(j);
}
int maxWidth = rect.size();
// Now we can look for next lines below rect.get(0), ... get(maxWidth - 1),
// continuously diminishing maxWidth till 0.
// When we need to diminish maxWidth, we can look wether the original
// maxWidth by (currentY - 1) is a maximum result.
...
}
So we walk:
+-------------+ 1st rect
| |
| | 2nd rect
| | 3rd rect
| | 4th rect
Demonstration of O(N²) complexity:
public static void main(String[] args) {
int[][] openCoords = {
{0, 2},
{1, 0},
{1, 1},
{1, 2},
{2, 0},
{2, 1}
};
new MaxRectFinder().find(openCoords);
}
private int[] maximumTopLeft;
private int[] maximumSize;
private void find(int[][] openCoords) {
maximumTopLeft = null;
maximumSize = new int[2];
for (int topLeftCandidateI = 0; topLeftCandidateI < openCoords.length; ++topLeftCandidateI) {
int yOrig = openCoords[topLeftCandidateI][0];
int xOrig = openCoords[topLeftCandidateI][1];
int y = yOrig;
int x = xOrig + 1;
int j = topLeftCandidateI + 1;
while (j < openCoords.length
&& openCoords[j][0] == y
&& openCoords[j][1] == x) {
++x;
++j;
}
// Now we have a maximum x.
for (;;) {
// Skip after right side on current line:
while (j < openCoords.length
&& openCoords[j][0] == y) {
++j;
}
++y;
// Check for maximum:
if (maximumTopLeft == null || (y - yOrig)*(x - xOrig) > maximumSize[0] * maximumSize[1]) {
maximumSize[0] = y - yOrig;
maximumSize[1] = x - xOrig;
maximumTopLeft = openCoords[topLeftCandidateI];
}
// Skip before left side below origin:
while (j < openCoords.length
&& openCoords[j][0] == y
&& openCoords[j][1] < x) {
++j;
}
if (j >= openCoords.length
|| openCoords[j][0] != y
|| openCoords[j][1] != x) {
break;
}
// Register rectangle part:
int x2 = xOrig;
while (j < openCoords.length
&& openCoords[j][0] == y
&& openCoords[j][1] == x2
&& x2 <= x) {
++x2;
++j;
}
x = x2;
}
}
if (maximumTopLeft == null) {
System.out.println("No solution found, not even 1x1.");
} else {
System.out.printf("At [%d, %d] with size [%d, %d].%n",
maximumTopLeft[0], maximumTopLeft[1], maximumSize[0], maximumSize[1]);
}
}
My previous answer was the simple approach. This a completely different one.
Algorithm
Identify horizontal runs and transform to rectangle notation.
Initialize currRects list with rectangles in row 0.
Set currRow to 1.
For each rectangle b in currRects, find intersections with horizontal runs a in row currRow. An intersect operation i is defined as
r(axi-axt,ayi-ayt) i r(bxi-bxt,byi-byt)
Its relevance is how both rectangle's y range intersect. Depicting it graphically:
bbb
aa| | No intersect
aa|aa | Partial intersect
aa|aaa| a contains b
aa|aaa|a a contains b
|aa | b contains a
|aaa| a equal b
|aaa|a a contains b
| aa| b contains a
| aa|a Partial intersect
| |aa No intersect
The necessary logic to determine each case is based in ayi, ayt, byi, and byt and simple, thus not described here.
This function will return a list of up to 2 rectangles and a flag.
No intersect ([],true)
Partial intersect: ([red,a],true)
b contains a: ([red],true)
a contains b: ([pres,a],false)
a equal b: ([pres],false)
red and pres are the result of combining the previous rectangle b with the incoming a. It can be preserving the width (in the sense of y coordinates) of the rectangle, or reducing it, but the difference is not important algorithmically.
The core of step 4 is to keep a list nextCurrRects with all the rectangles returned by function intersect. nextCurrRects should be initially empty, of course. Additionally, if for a rectangle b in the previous currRects the returned flag is never false, then b needs to be put in the final resulting list (or just printed or "yielded").
Make currRects equal to nextCurrRects. Iterate if currRow has not reached the end.
All rectangles still in currRects also belong to the result.
Example
1) inRects= [ r(0-0,2-2), r(1-1,0-2), r(2-2,0-1) ]
2) currRects= [ r(0-0,2-2) ]
3) currRow= 1
4)
nextCurrRects= []
r(1-1,0-2) i r(0-0,2-2) {a contains b} == ( [ r(0-1,2-2), r(1-1,0-2)] ], false )
nextCurrRects == [ r(0-1,2-2), r(1-1,0-2)] ]
5) currRects == [ r(0-1,2-2), r(1-1,0-2)] ]
4)
nextCurrRects= []
r(2-2,0-1) i r(0-1,2-2) {No intersect} == ( [], true )
Never false -> result= [ r(0-1,2-2) ]
r(2-2,0-1) i r(1-1,0-2) {Partial intersect} == ( r(1-2,0-1), true )
nextCurrRects= [ r(1-2,0-1) ]
Never false -> result= [ r(0-1,2-2) , r(1-2,0-1) ]
5) currRects= [ r(1-2,0-1) ]
6) result= [ r(0-1,2-2) , r(1-2,0-1) , r(1-2,0-1) ]
In fact, the algorithm just "discovered" that there is a 3rd resulting rectangle not considered in the original example:
[x][x][3]
[ ][ ][3]
[ ][ ][x]
Code
class Range:
def __init__(self,start,end=None):
self.start= start
self.end= end if end is not None else start
def isEmpty(self):
return self.start > self.end
def isUnit(self):
return self.start == self.end
def intersect(self,other):
return Range( max(self.start,other.start) , min(self.end,other.end) )
def contains(self,other):
return self.start <= other.start and self.end >= other.end
def __repr__(self):
return "Range(%d,%d)" % ( self.start, self.end )
class Rect:
def __init__(self,xRange,yRange):
self.xRange= xRange
self.yRange= yRange
def isEmpty(self):
return self.xRange.isEmpty() or self.yRange.isEmpty()
def isUnit(self):
return self.xRange.isUnit() and self.yRange.isUnit()
def intersect(self,other):
return Range( max(self.start,other.start) , min(self.end,other.end) )
def contains(self,other):
return self.xRange.contains(other.xRange) and self.yRange.contains(other.yRange)
def __repr__(self):
return "Rect(%s,%s)" % ( self.xRange, self.yRange )
def intersect(a,b):
r= Rect( Range(b.xRange.start,a.xRange.end) , a.yRange.intersect(b.yRange) )
brokenB= not a.yRange.contains(b.yRange)
fullyAbsorbedA= b.yRange.contains(a.yRange)
return (r,brokenB,fullyAbsorbedA)
def findOpenRectangles(freeElements,pastRowNum):
# From `freeElements`, compute free runs into `freeRunsPerRow`
from collections import defaultdict
freeRunsPerRow= defaultdict(set)
rowNum= -1
currRun= None
for fe in freeElements :
if fe[0] != rowNum :
if currRun is not None:
freeRunsPerRow[rowNum]|= { Rect(Range(rowNum),currRun) }
currRun= Range(fe[1],fe[1])
rowNum= fe[0]
elif fe[1] == currRun.end + 1 :
currRun= Range(currRun.start,fe[1])
else:
freeRunsPerRow[rowNum]|= { Rect(Range(rowNum),currRun) }
currRun= Range(fe[1],fe[1])
if currRun is not None:
freeRunsPerRow[rowNum]|= { Rect(Range(rowNum),currRun) }
currRun= None
for freeRuns in freeRunsPerRow.items() :
print( freeRuns )
# Yield open rectangles
currRects= set()
for currRow in range(0,pastRowNum) :
continuingRects= set()
startingRects= set( freeRunsPerRow[currRow] )
for b in currRects :
brokenB= True
for a in freeRunsPerRow[currRow] :
modifiedContinuingRect, t_brokenB, t_absorbedA= intersect(a,b)
if not modifiedContinuingRect.isEmpty() and not [ x for x in continuingRects if x.contains(modifiedContinuingRect) ] :
continuingRects-= { x for x in continuingRects if modifiedContinuingRect.contains(x) }
continuingRects|= {modifiedContinuingRect}
if not t_brokenB : brokenB= False
if t_absorbedA : startingRects-= {a}
if brokenB and not b.isUnit() : yield b
currRects= continuingRects
currRects|= startingRects
for b in currRects :
if not b.isUnit() : yield b
Test/Example
Using the following test code:
input= []
input.append(" X ")
input.append(" ")
input.append(" X ")
input.append(" X X")
input.append(" ")
input.append(" ")
input.append(" X ")
input.append(" X X ")
input.append(" X X")
# Translates input into a list of coordinates of free elements
freeElements= []
for rowNum, row in enumerate(input):
for colNum, element in enumerate(row):
if element == " " :
freeElements.append( (rowNum,colNum) )
for fe in freeElements :
print( fe )
# Find and print open rectangles
for openRect in findOpenRectangles(freeElements,len(input)) :
print( openRect )
Output is the following (some formatting to save space and titles added):
freeElements
(0, 0), (0, 1), (0, 2), (0, 4), (0, 5), (0, 6), (0, 7)
(1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7)
(2, 0), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7)
(3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (3, 6)
(4, 0), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (4, 6), (4, 7)
(5, 0), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5), (5, 6), (5, 7)
(6, 0), (6, 1), (6, 2), (6, 3), (6, 5), (6, 6), (6, 7)
(7, 0), (7, 1), (7, 2), (7, 4), (7, 5), (7, 7)
(8, 0), (8, 2), (8, 3), (8, 4), (8, 5), (8, 6)
freeRunsPerRow
(0, {Rect(Range(0,0),Range(0,2)), Rect(Range(0,0),Range(4,7))})
(1, {Rect(Range(1,1),Range(0,7))})
(2, {Rect(Range(2,2),Range(2,7)), Rect(Range(2,2),Range(0,0))})
(3, {Rect(Range(3,3),Range(6,6)), Rect(Range(3,3),Range(0,4))})
(4, {Rect(Range(4,4),Range(0,7))})
(5, {Rect(Range(5,5),Range(0,7))})
(6, {Rect(Range(6,6),Range(5,7)), Rect(Range(6,6),Range(0,3))})
(7, {Rect(Range(7,7),Range(7,7)), Rect(Range(7,7),Range(4,5)), Rect(Range(7,7),Range(0,2))})
(8, {Rect(Range(8,8),Range(0,0)), Rect(Range(8,8),Range(2,6))})
findOpenRectangles(freeElements,len(input))
Rect(Range(0,1),Range(0,2))
Rect(Range(1,1),Range(0,7))
Rect(Range(0,2),Range(4,7))
Rect(Range(1,2),Range(2,7))
Rect(Range(3,5),Range(0,4))
Rect(Range(0,5),Range(4,4))
Rect(Range(4,5),Range(0,7))
Rect(Range(1,5),Range(2,4))
Rect(Range(1,6),Range(2,3))
Rect(Range(4,6),Range(5,7))
Rect(Range(0,6),Range(6,6))
Rect(Range(3,6),Range(0,3))
Rect(Range(3,7),Range(0,2))
Rect(Range(4,7),Range(7,7))
Rect(Range(8,8),Range(2,6))
Rect(Range(7,8),Range(4,5))
Rect(Range(0,8),Range(2,2))
Rect(Range(4,8),Range(5,5))
Rect(Range(0,8),Range(0,0))
Test/Example Conclusion
Output is correct. All non-trivial rectangles are present.