заменить цикл для итерации двумя строками с несколькими, если условие Python - PullRequest
0 голосов
/ 30 ноября 2018

У меня следующий код, я использую цикл для дальнейшей работы.

for i in range(0,(len(dff1)-1)):
    lat1=dff1.latitude.values[i]
    lon1=dff1.longitude.values[i]
    lat2=dff1.latitude.values[i+1]
    lon2=dff1.longitude.values[i+1]
    if((lat1!=0)&(lon1!=0)&(lat2!=0)&(lon2!=0)):
        a=(lat1,lon1)
        b=(lat2,lon2)
        s=i
        dist.append(great_circle(a,b).meters)
    elif((lat1==0)&(lon1==0)&(lat2==0)&(lon2==0)):
        dist.append(0)
    elif((lat1!=0)&(lon1!=0)&(lat2==0)&(lon2==0)):
        dist.append(0)
    elif((lat1==0)&(lon1==0)&(lat2!=0)&(lon2!=0)):
        pp=list(range(s,i+1))
        lst=[]
        for y in pp:
            lst.append(dff1.latitude.values[y])
        ls = [z for z, e in enumerate(lst) if e != 0]
        lst1=[]
        for q in pp:
            lst1.append(dff1.longitude.values[q])
        ls = [z for z, e in enumerate(lst) if e != 0]
        ls1 = [z for z, e in enumerate(lst1) if e != 0]
        lat1=lst[ls[-1]]
        lon1=lst1[ls[-1]]
        a=(lat1,lon1)
        b=(lat2,lon2)
        dist.append(great_circle(a,b).meters)

Я храню значения lat, long из каждой строки и их предыдущей строки. Я получаю 4 переменные, т.е. lat1, lon1, lat2, lon2, Теперь я использую условия, как будто все значения переменных равны нулю, добавляю 0, как будто у меня есть 4 условия, и использую другую функцию, называемую great_circle, чтобы вычислить некоторое значение с этими четырьмя переменными с последним условием, записанным в коде, и добавлением егок списку.

Я хочу заменить цикл, так как его выполнение выполняется слишком долго, когда размер фрейма данных большой.

Как это сделать без цикла, чтобы он мог выполнятьсябыстрее

1 Ответ

0 голосов
/ 30 ноября 2018

Так что, если я вас правильно понимаю, у вас есть фрейм данных с долготой и широтой, и вы хотите рассчитать расстояние до долготы и широты, расположенное в следующей строке, и сохранить это значение как расстояние.

Фиктивный фрейм данных:

df = pd.DataFrame({'Long':[-2986.242495,-3383.296608,0,0],'Lat':[-880.627428,-2559.748913,0,0]})

df
Lat             Long
-880.627428     -2986.242495
-2559.748913    -3383.296608
0.000000        0.000000
0.000000        0.000000

вместо выполнения цикла, в котором вы назначаете i + 1 для lat2 и long2, вы можете просто сдвинуть фрейм данных и сохранить значения в новых столбцах, как показано ниже

df[['Long_2','Lat_2']] = df[['Long','Lat']].shift(-1)

df
Lat             Long            Long_2          Lat_2
-880.627428     -2986.242495    -3383.296608    -2559.748913
-2559.748913    -3383.296608    0.000000        0.000000
0.000000        0.000000        0.000000        0.000000
0.000000        0.000000        NaN             NaN

тогда мы можем создать столбцы расстояния, которые мы даем None как значение по умолчанию, и 0, где все столбцы равны 0

df['Distance'] = None
df.loc[(df.Lat==0) & (df.Long==0) & (df.Lat_2==0) & (df.Long_2==0),'Distance'] = 0

, где все столбцы не равны 0, мы используем нашу формулу расстояния для вычисления расстояния

df.loc[df.Distance!=0,'Distance'] = sphere_dist(df.loc[df.Distance!=0,'Lat'],df.loc[df.Distance!=0,'Long'],df.loc[df.Distance!=0,'Lat_2'],df.loc[df.Distance!=0,'Long_2'])

и теперь у нас есть датафрейм с результатом, который мы (будем надеяться) после, в столбцах расстояния

df
Lat              Long           Long_2          Lat_2            Distance
-880.627428     -2986.242495    -3383.296608    -2559.748913    12400
-2559.748913    -3383.296608    0.000000        0.000000        14239.1
0.000000        0.000000        0.000000        0.000000        0
0.000000        0.000000        NaN             NaN             NaN

Формула, которую я здесь использовал, это

def sphere_dist(pickup_lat, pickup_lon, dropoff_lat, dropoff_lon):
    """
    Return distance along great radius between first and second coordinates.
    """
    #Define earth radius (km)
    R_earth = 6371
    #Convert degrees to radians
    pickup_lat, pickup_lon, dropoff_lat, dropoff_lon = map(np.radians,
                                                             [pickup_lat, pickup_lon, 
                                                              dropoff_lat, dropoff_lon])
    #Compute distances along lat, lon dimensions
    dlat = dropoff_lat - pickup_lat
    dlon = dropoff_lon - pickup_lon

    #Compute haversine distance
    a = np.sin(dlat/2.0)**2 + np.cos(pickup_lat) * np.cos(dropoff_lat) * np.sin(dlon/2.0)**2

    return 2 * R_earth * np.arcsin(np.sqrt(a))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...