2013-04-16 8 views
47

Mam Pandas DataFrame i chcę połączyć kolumny "długie" i "długie", aby utworzyć krotkę.Jak utworzyć krotkę z dwóch kolumn w Pandach

<class 'pandas.core.frame.DataFrame'> 
Int64Index: 205482 entries, 0 to 209018 
Data columns: 
Month   205482 non-null values 
Reported by  205482 non-null values 
Falls within 205482 non-null values 
Easting   205482 non-null values 
Northing  205482 non-null values 
Location  205482 non-null values 
Crime type  205482 non-null values 
long   205482 non-null values 
lat    205482 non-null values 
dtypes: float64(4), object(5) 

Kod Próbowałem użyć było:

def merge_two_cols(series): 
    return (series['lat'], series['long']) 

sample['lat_long'] = sample.apply(merge_two_cols, axis=1) 

Jednak ten zwrócił następujący błąd:

--------------------------------------------------------------------------- 
AssertionError       Traceback (most recent call last) 
<ipython-input-261-e752e52a96e6> in <module>() 
     2  return (series['lat'], series['long']) 
     3 
----> 4 sample['lat_long'] = sample.apply(merge_two_cols, axis=1) 
     5 

...

AssertionError: Block shape incompatible with manager 

Jak mogę Rozwiąż ten problem?

+0

Bardziej wygodna metoda wykorzystuje 'itertuples'. [Zobacz tę odpowiedź poniżej] (https://stackoverflow.com/a/47146412/3707607) –

Odpowiedz

77

Uzyskaj wygodę dzięki zip. Przydaje się przy danych kolumnowych.

df['new_col'] = list(zip(df.lat, df.long)) 

Jest mniej skomplikowane i szybsze niż przy użyciu apply lub map. Coś takiego jak np.dstack jest dwa razy szybsze niż zip, ale nie dałoby ci krotek.

+9

Powoduje zwrócenie obiektów zip, a nie krotek. –

+1

w python3, musisz użyć 'list'. To powinno działać: 'df ['new_col'] = list (zip (df.lat, df.long))' – paulwasit

+0

@paulwasit ah tak, moja miłość nienawidzi związku z leniwym zachowaniem Pythona 3. dzięki. –

37
In [10]: df 
Out[10]: 
      A   B  lat  long 
0 1.428987 0.614405 0.484370 -0.628298 
1 -0.485747 0.275096 0.497116 1.047605 
2 0.822527 0.340689 2.120676 -2.436831 
3 0.384719 -0.042070 1.426703 -0.634355 
4 -0.937442 2.520756 -1.662615 -1.377490 
5 -0.154816 0.617671 -0.090484 -0.191906 
6 -0.705177 -1.086138 -0.629708 1.332853 
7 0.637496 -0.643773 -0.492668 -0.777344 
8 1.109497 -0.610165 0.260325 2.533383 
9 -1.224584 0.117668 1.304369 -0.152561 

In [11]: df['lat_long'] = df[['lat', 'long']].apply(tuple, axis=1) 

In [12]: df 
Out[12]: 
      A   B  lat  long        lat_long 
0 1.428987 0.614405 0.484370 -0.628298  (0.484370195967, -0.6282975278) 
1 -0.485747 0.275096 0.497116 1.047605  (0.497115615839, 1.04760475074) 
2 0.822527 0.340689 2.120676 -2.436831  (2.12067574274, -2.43683074367) 
3 0.384719 -0.042070 1.426703 -0.634355  (1.42670326172, -0.63435462504) 
4 -0.937442 2.520756 -1.662615 -1.377490  (-1.66261469102, -1.37749004179) 
5 -0.154816 0.617671 -0.090484 -0.191906 (-0.0904840623396, -0.191905582481) 
6 -0.705177 -1.086138 -0.629708 1.332853  (-0.629707821728, 1.33285348929) 
7 0.637496 -0.643773 -0.492668 -0.777344 (-0.492667604075, -0.777344111021) 
8 1.109497 -0.610165 0.260325 2.533383  (0.26032456699, 2.5333825651) 
9 -1.224584 0.117668 1.304369 -0.152561  (1.30436900612, -0.152560909725) 
+0

To jest genialne. Dziękuję Ci. Oczywiste jest, że muszę się skupić na funkcjach lambda. – elksie5000

+0

Czy to działa na Twoje dane? Jeśli tak, czy możesz udostępnić swoją wersję pand i dane? Zastanawiam się, dlaczego twój kod nie działa, powinien. –

+0

Wersja to 0.10.1_20130131. Przepraszam za ignorancję, ale jaki jest najlepszy sposób na przesłanie fragmentu danych? (Wciąż względny początkujący). – elksie5000

0

Pandy ma metodę itertuples dokładnie to zrobić:

list(df[['lat', 'long']].itertuples(index=False, name=None)) 
Powiązane problemy