2013-05-09 29 views
9

Funkcja pandy factorize przypisuje każdą unikatową wartość w szeregu do kolejnego, opartego na 0 indeksowaniu, i oblicza, do którego indeksu należy każdy wpis z serii.Wielokolumnowy faktoryzacja w pandach

chciałbym osiągnąć równowartość pandas.factorize na wielu kolumnach:

import pandas as pd 
df = pd.DataFrame({'x': [1, 1, 2, 2, 1, 1], 'y':[1, 2, 2, 2, 2, 1]}) 
pd.factorize(df)[0] # would like [0, 1, 2, 2, 1, 0] 

Oznacza to, że chcę, aby określić każdą wyjątkową krotki wartości w kilku kolumnach ramki danych, przypisać indeks do sekwencyjnego każdy i obliczyć indeks, do którego należy każdy wiersz w ramce danych.

Factorize działa tylko na pojedynczych kolumnach. Czy w pandach istnieje funkcja podobna do wielu kolumn?

+0

Jaki jest twój oczekiwany wynik? – waitingkuo

+0

Lista w komentarzu - unikalny, sekwencyjny indeks dla każdej odrębnej wartości (x, y). – ChrisB

Odpowiedz

11

Musisz stworzyć ndarray o Najpierw k tuple, pandas.lib.fast_zip potrafi to zrobić bardzo szybko w pętli cytonowej.

import pandas as pd 
df = pd.DataFrame({'x': [1, 1, 2, 2, 1, 1], 'y':[1, 2, 2, 2, 2, 1]}) 
print pd.factorize(pd.lib.fast_zip([df.x, df.y]))[0] 

wyjście jest:

[0 1 2 2 1 0] 
+0

Dzięki - to daje odpowiedź, której szukam, w rozsądnie zwartej formie – ChrisB

0

Można użyć drop_duplicates spadać te zduplikowane wiersze

In [23]: df.drop_duplicates() 
Out[23]: 
     x y 
    0 1 1 
    1 1 2 
    2 2 2 

EDIT

Aby osiągnąć swój cel, możesz dołączyć oryginał df do drop_duplicated jednym:

In [46]: df.join(df.drop_duplicates().reset_index().set_index(['x', 'y']), on=['x', 'y']) 
Out[46]: 
    x y index 
0 1 1  0 
1 1 2  1 
2 2 2  2 
3 2 2  2 
4 1 2  1 
5 1 1  0 
+0

Nie chcę ich upuszczać, ale przypisać unikalny indeks do każdej pary różnych wartości (tzn. dodać nową kolumnę do ramki danych, z wartościami [0, 1, 2, 2, 1, 0]). – ChrisB

+0

Zaktualizowałem swoją odpowiedź, czy teraz spełnia ona Twój problem? – waitingkuo

1

jestem nie jestem pewien, czy to jest skuteczne rozwiązanie. Mogą być lepsze rozwiązania.

arr=[] #this will hold the unique items of the dataframe 
for i in df.index: 
    if list(df.iloc[i]) not in arr: 
     arr.append(list(df.iloc[i])) 

tak drukowania ARR nie daje

>>>print arr 
[[1,1],[1,2],[2,2]] 

do przechowywania indeksów, chciałbym zadeklarować ind tablica

ind=[] 
for i in df.index: 
    ind.append(arr.index(list(df.iloc[i]))) 

druk ind dałoby

>>>print ind 
[0,1,2,2,1,0] 
0
df = pd.DataFrame({'x': [1, 1, 2, 2, 1, 1], 'y':[1, 2, 2, 2, 2, 1]}) 
tuples = df[['x', 'y']].apply(tuple, axis=1) 
df['newID'] = pd.factorize(tuples)[0] 
+1

Wyjaśnij swój kod –

+0

Proszę wyjaśnij, co twój kod robi inaczej niż OP i jak to rozwiązuje problem. Polecam ten przewodnik na temat tworzenia przydatnej odpowiedzi https://stackoverflow.com/help/how-to-answer –