ich habe eine Punktlioste mit dreidimensionalen Punkten und will die Punkte herausfiltern, welche im X-Wert und Y-Wert in einem bestimmten Bereich liegen. will zum Beispiel alle Punkte, die im ersten Wert zwischen 4984.300 und 4984.800 und im zweiten zwischen 1047.500 und 1047.700 liegen. Einlesen und aufsplitten ist gemacht, also es sind schon Punkte mit X Y und Z, aber die Filterung ist mir ein Rätsel, vielen dank im Voraus
4984.407630 1047.532970 100.270170
4984.554300 1047.526320 99.915140
4984.672510 1047.561360 100.274070
4984.700930 1047.515300 100.573110
4984.495890 1047.505500 99.914170
4984.731800 1047.579040 99.977040
4984.735920 1047.572990 99.918050
4984.225030 1047.485850 100.147260
4983.969380 1047.436130 99.961370
4983.879480 1047.461770 100.079370
4984.321760 1047.447180 100.569280
4984.556990 1047.522430 100.452140
4984.293070 1047.491200 100.448240
4984.732170 1047.578270 100.156040
4984.638980 1047.504840 100.513140
4984.545400 1047.540250 99.974130
4984.042560 1047.436050 100.506360
4984.229240 1047.480160 100.448270
4984.227210 1047.482200 99.967260
4984.037680 1047.443520 100.084350
4983.900520 1047.431000 100.202400
4984.730930 1047.579020 100.275040
4984.312190 1047.462880 100.509260
4984.749610 1047.551180 99.860070
4984.029130 1047.456620 100.264340
4984.683360 1047.545080 100.394090
4984.099340 1047.458270 100.326320
4984.096480 1047.463690 100.386310
4984.168540 1047.462570 100.207300
4984.510070 1047.483440 100.571190
Punktliste filtern
Na ja, schreib dir eine Funktion, die überprüft, ob ein konkreter Punkt deinen Kriterien entspricht und einen Wahrheitswert zurück liefert. Diese kannst du dann z.B. als Prädikat für die eingebaute 'filter'-Funktion nehmen, in einer List-Comprehension verwenden, oder auch ganz klassisch in einer Schleife.Xelfern hat geschrieben: Einlesen und aufsplitten ist gemacht, also es sind schon Punkte mit X Y und Z, aber die Filterung ist mir ein Rätsel
- DeaD_EyE
- User
- Beiträge: 1020
- Registriert: Sonntag 19. September 2010, 13:45
- Wohnort: Hagen
- Kontaktdaten:
Ich hoffe mal, dass ich deine Hausaufgaben gelöst habe...
Da es sich hier um Punkte (Koordinaten) handelt, würde ich zuerst eine namedtuple dafür anlegen:
Hier deine Liste mit Punkten in eine Variable liste gepackt:
Das sieht dann so aus:
Ich denke mal, dass du das in irgendeiner anderen Form vorliegen hast.
Nutze z.B. das Modul csv um z.B. mit csv-Dateien umzugehen.
Hier der eigentliche Teil, der dich interessieren wird:
Die Funktion sollte selbsterklärend sein.
Würde man so lesen: minr ist kleiner als value und value ist kleiner als maxr
So kannst du Prüfen, ob sich etwas in einem Bereich befindet (True) oder außerhalb des Bereichs ist (False).
Eine Funktion, die es ermöglicht verschiedene Bereiche anzugeben, aber nicht alle sind notwendig.
Als Listcomprehension lässt sich das ganze kompakter schreiben.
Die List-Comprehension für x würde man so als For-Schleife schreiben:
für x, y und z:
Die Module numpy und pandas haben für so etwas auch Funktionen/Methoden. Man lernt aber besser zuerst, wie man das mit der Standardlib macht und später kann man sich auf Module konzentrieren, die die Aufgabe besser und schneller erledigen.
Da es sich hier um Punkte (Koordinaten) handelt, würde ich zuerst eine namedtuple dafür anlegen:
Code: Alles auswählen
from collections import namedtuple
Point = namedtuple('Point', 'x y z')
Code: Alles auswählen
points_text = """4984.407630 1047.532970 100.270170
4984.554300 1047.526320 99.915140
4984.672510 1047.561360 100.274070
4984.700930 1047.515300 100.573110
4984.495890 1047.505500 99.914170
4984.731800 1047.579040 99.977040
4984.735920 1047.572990 99.918050
4984.225030 1047.485850 100.147260
4983.969380 1047.436130 99.961370
4983.879480 1047.461770 100.079370
4984.321760 1047.447180 100.569280
4984.556990 1047.522430 100.452140
4984.293070 1047.491200 100.448240
4984.732170 1047.578270 100.156040
4984.638980 1047.504840 100.513140
4984.545400 1047.540250 99.974130
4984.042560 1047.436050 100.506360
4984.229240 1047.480160 100.448270
4984.227210 1047.482200 99.967260
4984.037680 1047.443520 100.084350
4983.900520 1047.431000 100.202400
4984.730930 1047.579020 100.275040
4984.312190 1047.462880 100.509260
4984.749610 1047.551180 99.860070
4984.029130 1047.456620 100.264340
4984.683360 1047.545080 100.394090
4984.099340 1047.458270 100.326320
4984.096480 1047.463690 100.386310
4984.168540 1047.462570 100.207300
4984.510070 1047.483440 100.571190"""
points = [Point(*map(float, p.split())) for p in points_text.splitlines()]
Code: Alles auswählen
>>> points[:4]
[Point(x=4984.40763, y=1047.53297, z=100.27017),
Point(x=4984.5543, y=1047.52632, z=99.91514),
Point(x=4984.67251, y=1047.56136, z=100.27407),
Point(x=4984.70093, y=1047.5153, z=100.57311)]
Nutze z.B. das Modul csv um z.B. mit csv-Dateien umzugehen.
Hier der eigentliche Teil, der dich interessieren wird:
Code: Alles auswählen
def in_range(value, minr, maxr):
return minr < value < maxr
Würde man so lesen: minr ist kleiner als value und value ist kleiner als maxr
So kannst du Prüfen, ob sich etwas in einem Bereich befindet (True) oder außerhalb des Bereichs ist (False).
Eine Funktion, die es ermöglicht verschiedene Bereiche anzugeben, aber nicht alle sind notwendig.
Code: Alles auswählen
def filter_points(points, ranges):
for point in points:
if all(in_range(getattr(point, axis), *min_max) for (axis, min_max) in ranges.items()):
yield point
ranges = {
'x': [4984.0, 4985.0],
'y': [1047.48,1047.49],
'z': [100.44, 100.45],
}
result = list(filter_points(points, ranges))
Code: Alles auswählen
# nur für x
[point for point in points if 4984.5 < point.x < 4985.0]
# für x und y
[point for point in points if 4984.5 < point.x < 4985.0 and 1047.52 < point.y < 1047.53]
# für x, y und z
[point for point in points if 4984.5 < point.x < 4985.0 and 1047.52 < point.y < 1047.53 and 100.0 < point.z < 105]
Code: Alles auswählen
result = []
for point in points:
if 4984.5 < point.x < 4985.0:
result.append(point)
Code: Alles auswählen
result = []
for point in points:
if 4984.5 < point.x < 4985.0 and 1047.52 < point.y < 1047.53 and 100.0 < point.z < 105:
result.append(point)
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
also ich benutze phyton in der Dynamo for Revit- Umgebung, daran finde ich nicht den Anschluss, also ich habe eine Liste mit den Punkten:
List
Point(X = 4984.407630, Y = 1047.532970, Z = 100.272170))
Point(X = 4984.468530, Y = 1047.529740, Z = 100.305550))
Point(X = 4984.389546, Y = 1047.531970, Z = 100.257820))
Point(X = 4984.416930, Y = 1047.530970, Z = 100.246140))
der Phytonknoten beginnt immer mit:
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
# Import RevitNodes
clr.AddReference("RevitNodes")
import Revit
# Import Revit elements
from Revit.Elements import *
# Import DocumentManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
import System
#define inputs
punktliste = IN[0]
minx = IN[1]
miny = IN[2]
minz = IN[3]
maxx = IN[4]
maxy = IN[5]
maxz = IN[6]
die vorher gezeigte Punktliste ist als Input 0 deklariert und die die min und max punkte zeigen jeweils die Grenzwerte. Wie greif ich nun richtig auf die Punktliste zu, ich hab die Vorschlägevon DeaD_EyE alle ohne Erfolg probiert. Problem ist scheinbar die Anbindung. Weiß da jemand wie das geht?
List
Point(X = 4984.407630, Y = 1047.532970, Z = 100.272170))
Point(X = 4984.468530, Y = 1047.529740, Z = 100.305550))
Point(X = 4984.389546, Y = 1047.531970, Z = 100.257820))
Point(X = 4984.416930, Y = 1047.530970, Z = 100.246140))
der Phytonknoten beginnt immer mit:
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
# Import RevitNodes
clr.AddReference("RevitNodes")
import Revit
# Import Revit elements
from Revit.Elements import *
# Import DocumentManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
import System
#define inputs
punktliste = IN[0]
minx = IN[1]
miny = IN[2]
minz = IN[3]
maxx = IN[4]
maxy = IN[5]
maxz = IN[6]
die vorher gezeigte Punktliste ist als Input 0 deklariert und die die min und max punkte zeigen jeweils die Grenzwerte. Wie greif ich nun richtig auf die Punktliste zu, ich hab die Vorschlägevon DeaD_EyE alle ohne Erfolg probiert. Problem ist scheinbar die Anbindung. Weiß da jemand wie das geht?
- DeaD_EyE
- User
- Beiträge: 1020
- Registriert: Sonntag 19. September 2010, 13:45
- Wohnort: Hagen
- Kontaktdaten:
Ohne jetzt feste nachzudenken, behaupte ich mal, dass man das mit filter kürzer schreiben kann ^^Sirius3 hat geschrieben:@DeaD_EyE: für filter_points könnte man auch direkt die Standardfunktion `filter` verwenden und statt all(...) eine der direkten Bedingungen aus Deinen ListComprehensions.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server