2015-05-03 1 views
1

Я работаю с пакетом python под названием UTM, который преобразует координаты WGS84 в UTM и наоборот. Я хотел бы применить эту функцию к кадру данных pandas. Функция работает следующим образом:pandas - применить функцию UTM к столбцам данных данных

utm.from_latlon(51.2, 7.5) 
>>> (395201.3103811303, 5673135.241182375, 32, 'U') 

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

Я работаю на Dataframe называется cities как:

City;Latitude;Longitude;minx;maxx;miny;maxy 
Roma;41.892916;12.48252;11.27447419;13.69056581;40.99359439;42.79223761 
Paris;48.856614;2.352222;0.985506011;3.718937989;47.95729239;49.75593561 
Barcelona;41.385064;2.173403;0.974836927;3.371969073;40.48574239;42.28438561 
Berlin;52.519171;13.406091;11.92835553;14.88382647;51.61984939;53.41849261 
Moscow;55.755826;37.6173;36.01941671;39.21518329;54.85650439;56.65514761 

, и я хотел бы добавить четыре столбца для каждой строки под названием 'utmminx', 'utmmax', 'utmminy', '' как utmmaxy результат применения функции utm к столбцам «minx», «maxx», «miny», «maxy». До сих пор я попытался следующие, назначив первым и второе значение результирующего набора для новых столбцов:

cities['utmminx'],cities['utmmaxx'] = utm.from_latlon(cities['minx'],cities['maxx'])[0],utm.from_latlon(cities['minx'],cities['maxx'])[1] 

, но я получил ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all(). я попытался установить только первое значение строки функции и она работает :

utm.from_latlon(cities['minx'][0],cities['maxx'][0])[0],utm.from_latlon(cities['minx'][0],cities['maxx'][0])[1] 
>>> (357074.7837193568, 1246647.7959235134) 

Я хотел бы избежать классических петель над dataframe, как я думал, что это классический метод панды, чтобы сделать это.

ответ

2

Начиная с рамой

 City Latitude Longitude  minx  maxx  miny  maxy 
0  Roma 41.892916 12.482520 11.274474 13.690566 40.993594 42.792238 
1  Paris 48.856614 2.352222 0.985506 3.718938 47.957292 49.755936 
2 Barcelona 41.385064 2.173403 0.974837 3.371969 40.485742 42.284386 
3  Berlin 52.519171 13.406091 11.928356 14.883826 51.619849 53.418493 
4  Moscow 55.755826 37.617300 36.019417 39.215183 54.856504 56.655148 

Определим функцию, которая принимает строку, вызывает utm.from_latlon() и возвращает серию из двух первых элементов набора, которые мы получаем от UTM. Затем мы используем Pandas apply() для вызова этой функции. Я просто сделал один набор координат, но вы можете сделать то же самое заявление apply() для других.

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

def getUTMs(row): 
    tup = utm.from_latlon(row.ix[0],row.ix[1]) 
    return pd.Series(tup[:2]) 

cities[['utmminy','utmminx']] = cities[['miny','maxx']].apply(getUTMs , axis=1) 
cities 

     City Latitude Longitude  minx  maxx  miny \ 
0  Roma 41.892916 12.482520 11.274474 13.690566 40.993594 
1  Paris 48.856614 2.352222 0.985506 3.718938 47.957292 
2 Barcelona 41.385064 2.173403 0.974837 3.371969 40.485742 
3  Berlin 52.519171 13.406091 11.928356 14.883826 51.619849 
4  Moscow 55.755826 37.617300 36.019417 39.215183 54.856504 

     maxy  utmminy   utmminx 
0 42.792238 389862.562124 4538871.624816 
1 49.755936 553673.645924 5311803.556837 
2 42.284386 531525.080929 4481738.581782 
3 53.418493 491957.246518 5718764.545758 
4 56.655148 513814.029424 6078844.774914 
2

Вы можете использовать apply метод по столбцам, как

Использование функции лямбда

In [120]: lambdafunc = lambda x: pd.Series(utm.from_latlon(x['minx'], x['maxx'])[:2]) 

И, применяя по ряду причин

In [121]: cities[['utmminx', 'utmmax']] = cities.apply(lambdfunc), axis=1) 

In [122]: cities 
Out[122]: 
     City Latitude Longitude  minx  maxx  miny  maxy  utmminx   utmmax 
0  Roma 41.892916 12.482520 11.274474 13.690566 40.993594 42.792238 357074.783719 1246647.795924 
1  Paris 48.856614 2.352222 0.985506 3.718938 47.957292 49.755936 579990.155575 108936.764630 
2 Barcelona 41.385064 2.173403 0.974837 3.371969 40.485742 42.284386 541385.186664 107751.160445 
3  Berlin 52.519171 13.406091 11.928356 14.883826 51.619849 53.418493 487350.117333 1318634.001517 
4  Moscow 55.755826 37.617300 36.019417 39.215183 54.856504 56.655148 519389.217259 3986123.464910 
+0

Вау, мы действительно близки! Мне нравится лямбда. –

+0

Вы избили меня за секунды =) На самом деле это может быть однострочный, например 'cities.apply (lambda x: pd.Series (utm.from_latlon (x ['minx'], x ['maxx']) [: 2])), ось = 1) ', но пришлось разбить лямбда-функцию из-за длины и удобочитаемости! – Zero