파이썬 : 조건에 따라 줄 바꿈


11

각 정점 / 점과 관련된 데이터가있는 여러 줄 문자열의 geopandas 데이터 프레임이 있습니다.

Point_x = (Lat, Lon, Time, ID, Data1, Data2, Data3)

포인트는 ID를 기준으로 선 스트링으로 변환되고 시간순으로 정렬됩니다.

조건이 충족되는 지점에서 줄을 끊고 싶습니다. 지금은 포인트 사이의 거리가 어떤 값보다 클 때입니다. 미래에는 데이터 필드의 기능이 가치가있는 곳이 될 수 있습니다. 예를 들어, 속도가 5kph를 넘을 때 선 스트링을 분할하십시오.

현재 문제는 일부 트랙이 중복 ID를 가진 점으로 구성되어 있기 때문에 선 스트링이 큰 거리에서 앞뒤로 점프하며 이러한 선을 끊는 임계 값이 필요하다는 것입니다.

이것을 사용하는 라이브러리 / 메소드를 구성하는 올바른 방법에 대한 아이디어가 있습니까?

데이터 프레임에는 트랙 당 많은 포인트가있는 150k 개 이상의 트랙이 있으므로 효율성이 좋습니다.

트랙 DF의 예는 다음과 같습니다.

ID         geometry                                                  
204235000  LINESTRING (37.62001 -28.99535, 37.62015 -28.9...   
205400000  LINESTRING (3.807816666666666 -18.083181666666...   
207138000  LINESTRING (22.73206 -34.97915833333333, 22.73...   
209016000  LINESTRING (8.447673333333331 -23.522783333333...     

다음은 점 DF의 샘플입니다. Datetime, Point (Lon, Lat), Speed, Size 등 18 개의 열이 있습니다.

Index           Heading   Latitude  Longitude       ID  
20              92.8 -35.946802  13.089695  210725000               
21              93.5 -35.946912  13.091808  210725000               
22              95.4 -35.965520  13.497698  210725000               
23              94.7 -35.965803  13.501898  210725000               
24              94.9 -35.965987  13.504573  210725000               

편집 : 조금 더 명확하려고했습니다.


GeoDataFrame의 구조는 무엇입니까? 의 사본을 gd.head()환영합니다.
gene

머리를
보이

나는 과거에 GeoPy (geopy.distance.vincenty)를 비슷한 것으로 사용했습니다. 포인트를 연결해야했지만 결정된 임계 값보다 긴 경우 포인트를 연결하고 싶지 않았습니다. 함수를 통해 각 좌표 쌍을 전송하고 임계 값보다 작은 경우에만 연결했습니다. geopy.readthedocs.io/en/1.10.0/#geopy.distance.vincenty
JohnR

중복 ID 기능의 기본 키 / 정렬 조건은 무엇입니까 : 시간 대 ID 또는 ID 대 시간?
huckfinn

무슨 뜻인지 잘 모르겠습니다. 포인트는 ID별로 그룹화되고 시간별로 정렬 된 다음 라인 문자열을 생성하는 데 사용되는 정렬 된 위치입니다. ID는 때때로 개체간에 복제됩니다. 예 : 도시 A에 ID = '123'인 자동차가 있습니다. 그것은 위치와 시간을 전달하고 있습니다. 도시 B에는 ID = '123'인 자동차가 있으며 위치를 전송하고 시간이 인터리브됩니다. 이러한 점에서 구축 선은 A와 B 사이에서 뛰어 내리고 싶다
RedM

답변:


1

아직 shape / geopandas를 사용하지 않았으므로 의사 코드 만 제공 할 수 있습니다.

distance_threshold = 50 # Value at which distance to cut off
new_lines = [] # Array to hold the newly created, split lines
new_line_marker = 0 # Let's remember where our new line starts
for linestring in linestrings: # Iterate over all linestrings
  for i, coord in enumerate(linestring.coords[:-1]): # Iterate over all coords of the linestring
    if distance(coord, coords[i+1]) >= distance_threshold: # Check if threshold is met
      # If condition is met, we generate a new linestring,
      # starting from the last split to the current one
      new_lines[] = new LineString(coords[new_line_marker:i])
      new_line_marker = i+1 # remember to reset the marker

거리 함수는 라이브러리가 이미 제공하는 것이거나 직접 구현해야합니다 (친구 피타고라스가 도움이 될 것입니다).

거기에서 필요에 따라 효율성을 향상시킬 수 있지만 좋은 출발점이되어야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.