Мне потребовалось много времени, чтобы выяснить, но, наконец, вот простой способ перечислить содержимое подпапки в ведро S3 с помощью boto3. Надеюсь, что это поможет
prefix = "folderone/foldertwo/"
s3 = boto3.resource('s3')
bucket = s3.Bucket(name="bucket_name_here")
FilesNotFound = True
for obj in bucket.objects.filter(Prefix=prefix):
print('{0}:{1}'.format(bucket.name, obj.key))
FilesNotFound = False
if FilesNotFound:
print("ALERT", "No file in {0}/{1}".format(bucket, prefix))
Реализация формулы шнурка может быть выполнена в Numpy
. Предполагая эти вершины:
import numpy as np
x = np.arange(0,1,0.001)
y = np.sqrt(1-x**2)
Мы можем переопределить функцию в numpy, чтобы найти область:
def PolyArea(x,y):
return 0.5*np.abs(np.dot(x,np.roll(y,1))-np.dot(y,np.roll(x,1)))
И получить результаты:
print PolyArea(x,y)
# 0.26353377782163534
Избегать for
цикл делает эту функцию примерно в 50 раз быстрее, чем PolygonArea
:
%timeit PolyArea(x,y)
# 10000 loops, best of 3: 42 µs per loop
%timeit PolygonArea(zip(x,y))
# 100 loops, best of 3: 2.09 ms per loop.
Время выполняется в блокноте Jupyter.
Ответ maxb дает хорошую производительность, но может легко привести к потере точности, когда значения координат или количество точек велики. Это может быть смягчено простым сдвигом координат:
def polygon_area(x,y):
# coordinate shift
x_ = x - x.mean()
y_ = y - y.mean()
# everything else is the same as maxb's code
correction = x_[-1] * y_[0] - y_[-1]* x_[0]
main_area = np.dot(x_[:-1], y_[1:]) - np.dot(y_[:-1], x_[1:])
return 0.5*np.abs(main_area + correction)
Например, общей системой географической привязки является UTM, которая может иметь (x, y) координаты (488685.984, 7133035.984)
. Произведение этих двух значений равно 3485814708748.448
. Вы можете видеть, что этот единственный продукт уже на грани точности (он имеет то же количество десятичных разрядов, что и входные данные). Добавление лишь нескольких из этих продуктов, не говоря уже о тысячах, приведет к потере точности.
Простой способ смягчить это - сдвинуть многоугольник от больших положительных координат к чему-то ближе к (0,0), например, вычитая центроид, как в коде выше. Это помогает двумя способами:
,x.mean() * y.mean()
для каждого продукта Смещение координат не изменяет общую площадь, оно просто делает расчет более устойчивым в численном отношении.
Анализируя ответ Махди, я пришел к выводу, что большую часть времени проводил, занимаясь np.roll()
. Убрав необходимость в броске и все еще используя numpy, я сократил время выполнения до 4-5 мксек на цикл по сравнению с 41 мкс Махди (для сравнения, функция Махди в среднем занимала 37 мкс на моей машине).
def polygon_area(x,y):
correction = x[-1] * y[0] - y[-1]* x[0]
main_area = np.dot(x[:-1], y[1:]) - np.dot(y[:-1], x[1:])
return 0.5*np.abs(main_area + correction)
При вычислении корректирующего члена, а затем нарезке массивов, нет необходимости свернуть или создать новый массив.
Тесты:
10000 iterations
PolyArea(x,y): 37.075µs per loop
polygon_area(x,y): 4.665µs per loop
Время было сделано с использованием модуля time
и time.clock()
Вы можете использовать формулу шнурка , например,
def PolygonArea(corners):
n = len(corners) # of corners
area = 0.0
for i in range(n):
j = (i + 1) % n
area += corners[i][0] * corners[j][1]
area -= corners[j][0] * corners[i][1]
area = abs(area) / 2.0
return area
# examples
corners = [(2.0, 1.0), (4.0, 5.0), (7.0, 8.0)]
Это работает только для простых многоугольников sup>
Если у вас есть многоугольник с отверстиями : вычислите площадь внешнего кольца и вычтите области внутренних колец
Если у вас есть самопересекающиеся кольца : их нужно разложить на простые сектора
В приведенном выше коде есть ошибка, так как он не принимает абсолютные значения на каждой итерации. Приведенный выше код всегда будет возвращать ноль. (Математически это разница между взятием продукта со знаком или клина и реальной площадью http://en.wikipedia.org/wiki/Exterior_algebra .) Вот некоторый альтернативный код.
def area(vertices):
n = len(vertices) # of corners
a = 0.0
for i in range(n):
j = (i + 1) % n
a += abs(vertices[i][0] * vertices[j][1]-vertices[j][0] * vertices[i][1])
result = a / 2.0
return result
Это гораздо проще для правильных многоугольников:
import math
def area_polygon(n, s):
return 0.25 * n * s**2 / math.tan(math.pi/n)
, поскольку формула ¼ n s2 / tan (π / n). Учитывая количество сторон, n, и длину каждой стороны, s
На основании
https://www.mathsisfun.com/geometry/area-irregular-polygons.html
def _area_(coords):
t=0
for count in range(len(coords)-1):
y = coords[count+1][1] + coords[count][1]
x = coords[count+1][0] - coords[count][0]
z = y * x
t += z
return abs(t/2.0)
a=[(5.09,5.8), (1.68,4.9), (1.48,1.38), (4.76,0.1), (7.0,2.83), (5.09,5.8)]
print _area_(a)
Хитрость в том, что первая координата также должна быть последней.