2016-10-02 83 views
8

Mam df, która zawiera moje główne dane, które mają milion rows. Moje główne dane również mają 30 columns. Teraz chcę dodać kolejną kolumnę do mojego df o nazwie category. Numer category jest column w df2, który zawiera około 700 rows i dwa inne columns, które będą pasować do dwóch columns w df.Pandy zapełniają nową kolumnę słupków danych na podstawie pasujących kolumn w innej ramce danych

Zacznę ustawienie index w df2 i df że będzie pasował pomiędzy ramkami, jednak niektóre z index w df2 nie istnieje w df.

Pozostałe kolumny w df2 nazywane są AUTHOR_NAME i CATEGORY.

Odpowiednia kolumna w df nazywa się AUTHOR_NAME.

Niektóre z AUTHOR_NAME w df nie istnieje w df2 i na odwrót.

Dyspozycja chcę jest: kiedy index w df mecze z index w df2 i title w df mecze z title w df2, dodać category do df, jeszcze dodać NaN w category.

Przykład dane:

df2 
      AUTHOR_NAME    CATEGORY 
Index  
Pub1  author1     main 
Pub2  author1     main 
Pub3  author1     main 
Pub1  author2     sub 
Pub3  author2     sub 
Pub2  author4     sub 


df 
      AUTHOR_NAME  ...n amount of other columns   
Index  
Pub1  author1     
Pub2  author1  
Pub1  author2 
Pub1  author3 
Pub2  author4 

expected_result 
      AUTHOR_NAME    CATEGORY ...n amount of other columns 
Index 
Pub1  author1     main 
Pub2  author1     main 
Pub1  author2     sub 
Pub1  author3     NaN 
Pub2  author4     sub 

Jeśli używam df2.merge(df,left_index=True,right_index=True,how='left', on=['AUTHOR_NAME']) mój df staje się trzy razy większe niż to ma być.

Więc pomyślałem, że połączenie może być niewłaściwe. Naprawdę próbuję zrobić to użyć df2 jako tabeli odnośników, a następnie zwrócić wartości type do df w zależności od tego, czy spełnione są określone warunki.

def calculate_category(df2, d): 
    category_row = df2[(df2["Index"] == d["Index"]) & (df2["AUTHOR_NAME"] == d["AUTHOR_NAME"])] 
    return str(category_row['CATEGORY'].iat[0]) 

df.apply(lambda d: calculate_category(df2, d), axis=1) 

Jednak ta wyrzuca mi błąd:

IndexError: ('index out of bounds', u'occurred at index 7614') 
+0

nie jestem jeśli '' left_index on' i/right_index' praca razem pewien. Może potrzebujesz 'on = ['Index', 'AUTHOR_NAME']' (lub coś podobnego). I nie jestem pewien, która ramka danych pozostała w 'df2.merge (df, ...)'. Może potrzebujesz 'how =" right "' lub 'pd.merge (left = df, right = df2, ...)' – furas

Odpowiedz

7

Rozważmy następujący dataframes df i df2

df = pd.DataFrame(dict(
     AUTHOR_NAME=list('AAABBCCCCDEEFGG'), 
     title=  list('zyxwvutsrqponml') 
    )) 

df2 = pd.DataFrame(dict(
     AUTHOR_NAME=list('AABCCEGG'), 
     title  =list('zwvtrpml'), 
     CATEGORY =list('11223344') 
    )) 

opcja 1
merge

df.merge(df2, how='left') 

opcja 2
join

cols = ['AUTHOR_NAME', 'title'] 
df.join(df2.set_index(cols), on=cols) 

obie opcje uzyskując

enter image description here

+0

Po prostu szybka nuta ... która sprawdziła się dla mnie dobrze ... ale w niektórych przypadkach skończyłem z duplikatami ... wciąż nie jestem pewien co jest tego przyczyną ... ale zrezygnuj z duplikatów przechowujących tylko jeden (keep = pierwszy LUB keep = last) ... sprawdź dokumentację tutaj https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.drop_duplicates.html –

1

Sposób 1:

można użyć concat zamiast i upuść zduplikowane wartości obecne w obu Index i AUTHOR_NAME kolumn połączonych. Po tym, użyj isin członkostwa kontroli:

df_concat = pd.concat([df2, df]).reset_index().drop_duplicates(['Index', 'AUTHOR_NAME']) 
df_concat.set_index('Index', inplace=True) 
df_concat[df_concat.index.isin(df.index)] 

Image

Uwaga: Kolumna Index przyjmowana jest ustawiony jako kolumny indeksu zarówno dla DF's.


Sposób 2:

Zastosowanie join po ustawieniu kolumny indeksu prawidłowo w następujący sposób:

Image

+0

to dla mnie nie działa, nie wiem dlaczego – user3471881

+0

Cóż, działa to dla mnie . Czy użyłeś odpowiednich nazw dla kolumny "DFs", a także Czy twoja kolumna "Indeks" w obu ramkach jest ustawiona jako indeks? Sprawdź dokładnie. Pozwól mi edytować post z nazwami ustawionymi przez Ciebie. –

+0

Tak, kolumna "Indeks" w obu ramkach jest ustawiona jako indeks, a ja użyłem odpowiednich nazw dla 'DFs ' – user3471881