Closed ChoonB closed 3 weeks ago
1km내에 지하철역 찾는 코드를 아래와 같은 함수로 짰는데 시간이 너무 오래걸려서 다른 방식을 써보려 한다.
def find_subways_within_1km(row, subway_sorted):
subways_within_1km = []
for _, subway in subway_sorted.iterrows():
distance = geodesic((row['latitude'], row['longitude']), (subway['latitude'], subway['longitude'])).meters
if distance <= 1000:
subways_within_1km.append(subway['subway_code'])
elif distance > 1000 and len(subways_within_1km) > 0:
break
return len(subways_within_1km), subways_within_1km
from geopy.distance import geodesic
from typing import List
from tqdm import tqdm
subway = pd.read_csv(os.path.join(BASE_PATH, "subwayinfo.csv"))
train_data["lon_lat"] = train_data["longitude"].astype(str) + "-" + train_data["latitude"].astype(str)
train_data["lon_lat"] = train_data["lon_lat"].map(lambda x: x.split("-"))
subway["lon_lat"] = subway["longitude"].astype(str) + "-" + subway["latitude"].astype(str)
subway["lon_lat"] = subway["lon_lat"].map(lambda x: x.split("-"))
subway.head()
tqdm.pandas()
i = 0
def find_subways_within_1km(row) -> List[int]:
subway["result"] = subway["lon_lat"].map(
lambda x: True if geodesic((row[1], row[0]), (x[1], x[0])).meters <= 1000 else False)
sb = subway.loc[subway["result"] == True,].index.values.tolist()
subway.drop(columns=["result"], inplace=True)
return sb
train_sb_df = train_data[["apt_idx", "latitude", "longitude"]].drop_duplicates()
train_sb_df["lon_lat"] = train_sb_df["longitude"].astype(str) + "-" + train_sb_df["latitude"].astype(str)
train_sb_df["lon_lat"] = train_sb_df["lon_lat"].map(lambda x: x.split("-"))
result = train_sb_df["lon_lat"].progress_map(find_subways_within_1km)
from sklearn.neighbors import BallTree
# 지구의 평균 반경 (킬로미터 단위)
EARTH_RADIUS_KM = 6371.0
# 아파트의 위도와 경도를 라디안으로 변환
temp_df_rad = np.radians(temp_df[['latitude', 'longitude']].values)
# 지하철 역의 위도와 경도를 라디안으로 변환
subway_sorted_rad = np.radians(subway_sorted[['latitude', 'longitude']].values)
# BallTree 생성 (Haversine 거리 메트릭 사용)
tree = BallTree(subway_sorted_rad, metric='haversine')
# 반경 1km을 라디안으로 변환
radius = 1 / EARTH_RADIUS_KM # 약 0.000157 라디안
# 가장 가까운 지하철역과 거리 찾기
distances, indices = tree.query(temp_df_rad, k=1)
temp_df['nearest_subway_distance'] = distances.flatten() * EARTH_RADIUS_KM * 1000 # meters
temp_df['nearest_subway_idx'] = subway_sorted['subway_idx'].iloc[indices.flatten()].values
# 반경 1km 내의 지하철역 인덱스 찾기
indices_within_1km = tree.query_radius(temp_df_rad, r=radius)
# 반경 1km 내의 지하철역 개수
temp_df['num_subway_within_1km'] = [len(ind) for ind in indices_within_1km]
# 반경 1km 내의 지하철역 subway_idx 리스트
temp_df['list_subway_idx_within_1km'] = [subway_sorted['subway_idx'].iloc[ind].tolist() for ind in indices_within_1km]
# 반경 1km 내의 Interchange_station이 2 이상인 지하철역 존재 여부
interchange_counts = [subway_sorted['Interchange_station'].iloc[ind].ge(2).sum() for ind in indices_within_1km]
temp_df['has_Interchange_2_or_more'] = [count >= 1 for count in interchange_counts]
# 결과 확인
print(temp_df[['nearest_subway_idx', 'nearest_subway_distance', 'num_subway_within_1km',
'list_subway_idx_within_1km', 'has_Interchange_2_or_more']].head())
할당: @ChoonB 기본 subway 관련 가설
[x] 지하철역과 거리가 가까울 수록 가격이 높을 것이다.
[x] 가장 가까운 지하철이 무슨역인지가 가격에 영향이 있을 것이다.
[x] 특정 거리안에 몇개의 지하철이 있는지가 가격에 영향이 있을 것이다.
---------추가 가설