Mam dwie ramki danych pand, które mają wspólne wiersze.
Załóżmy, że ramka danych2 jest podzbiorem ramki danych1.
Jak mogę uzyskać wiersze ramki danych 1, których nie ma w ramce danych 2?
df1 = pandas.DataFrame(data = {'col1' : [1, 2, 3, 4, 5], 'col2' : [10, 11, 12, 13, 14]})
df2 = pandas.DataFrame(data = {'col1' : [1, 2, 3], 'col2' : [10, 11, 12]})
Odpowiedzi:
Jedną z metod byłoby przechowywanie wyniku scalenia wewnętrznego z obu plików dfs, a następnie możemy po prostu wybrać wiersze, gdy wartości jednej kolumny nie są wspólne:
EDYTOWAĆ
Inną metodą, którą znalazłeś, jest użycie,
isin
które utworzyNaN
wiersze, które możesz upuścić:Jednak jeśli df2 nie uruchamia wierszy w ten sam sposób, to nie zadziała:
wyprodukuje cały df:
źródło
df1[~df1.isin(df2)].dropna(how = 'all')
wydaje się załatwić sprawę. W każdym razie dzięki - twoja odpowiedź pomogła mi znaleźć rozwiązanie.isin
wymaga, aby oba dfs zaczynały się od tych samych wartości wierszy, więc na przykład, jeśli df2 był,df2 = pd.DataFrame(data = {'col1' : [2, 3,4], 'col2' : [11,12, 13]})
wtedy twoja metoda nie zadziałakeep=False
:df0.append(df1).drop_duplicates(keep=False)
domyślnie zachowuje pierwszy duplikat, chcesz usunąć wszystkie duplikatyAktualnie wybrane rozwiązanie daje nieprawidłowe wyniki. Aby poprawnie rozwiązać ten problem, możemy wykonać lewe połączenie od
df1
dodf2
, upewniając się, że najpierw otrzymamy tylko unikalne wierszedf2
.Najpierw musimy zmodyfikować oryginalny DataFrame, aby dodać wiersz z danymi [3, 10].
Wykonaj lewe łączenie, eliminując duplikaty
df2
, aby każdy rząddf1
złączeń miał dokładnie 1 wierszdf2
. Użyj tego parametru,indicator
aby zwrócić dodatkową kolumnę wskazującą, z której tabeli pochodzi wiersz.Utwórz warunek logiczny:
Dlaczego inne rozwiązania są złe
Kilka rozwiązań popełnia ten sam błąd - sprawdzają tylko, czy każda wartość jest niezależnie w każdej kolumnie, a nie razem w tym samym wierszu. Dodanie ostatniego wiersza, który jest unikalny, ale zawiera wartości z obu kolumn,
df2
ujawnia błąd:To rozwiązanie otrzymuje ten sam zły wynik:
źródło
df_all[df_all['_merge'] == 'left_only']
aby mieć df z wynikamiZakładając, że indeksy są spójne w ramkach danych (nie biorąc pod uwagę rzeczywistych wartości col):
źródło
df1
których NIE ma indeksówdf2.index
”. Więcej na temat negacji: stackoverflow.com/q/19960077/304209 (zaskakujące, nie znalazłem żadnych wzmianek o tyldach w dokumentach pandas).ValueError: Item wrong length x instead of y.
Jak już wspomniano, isin wymaga, aby kolumny i indeksy były takie same dla dopasowania. Jeśli dopasowanie powinno dotyczyć tylko zawartości wierszy, jednym ze sposobów uzyskania maski do filtrowania obecnych wierszy jest przekonwertowanie wierszy na (Multi) Indeks:
Jeśli indeks ma być brany pod uwagę, set_index ma argument słowa kluczowego, który dołącza kolumny do istniejącego indeksu. Jeśli kolumny nie są wyrównane, listę (df.columns) można zastąpić specyfikacjami kolumn, aby wyrównać dane.
można alternatywnie wykorzystać do stworzenia indeksów, choć wątpię, aby było to bardziej wydajne.
źródło
Załóżmy, że masz dwie ramki danych: df_1 i df_2 z wieloma polami (nazwy kolumn) i chcesz znaleźć tylko te wpisy w df_1, których nie ma w df_2 na podstawie niektórych pól (np. Field_x, fields_y), wykonaj następujące kroki.
Krok 1. Dodaj kolumnę klucz1 i klucz2 odpowiednio do df_1 i df_2.
Krok 2. Połącz ramki danych, jak pokazano poniżej. field_x i field_y są naszymi pożądanymi kolumnami.
Krok 3. Wybierz tylko te wiersze z df_1, w których klucz1 nie jest równy kluczowi2.
Step4.Drop key1 i key2.
Ta metoda rozwiąże Twój problem i działa szybko nawet w przypadku dużych zbiorów danych. Wypróbowałem to dla ramek danych z ponad 1 000 000 wierszy.
źródło
nieco później, ale warto sprawdzić parametr „wskaźnik” pd.merge.
Zobacz inne pytanie na przykład: Porównaj ramki danych PandaS i zwróć wiersze, których brakuje w pierwszym
źródło
możesz to zrobić za pomocą metody isin (dict) :
Wyjaśnienie:
źródło
Można również Concat
df1
,df2
:a następnie usuń wszystkie duplikaty:
źródło
Co powiesz na to:
źródło
Oto inny sposób rozwiązania tego:
Lub:
źródło
Mój sposób na zrobienie tego polega na dodaniu nowej kolumny, która jest unikalna dla jednej ramki danych i za pomocą tej opcji mogę wybrać, czy zachować wpis
To sprawia, że każdy wpis w df1 ma kod - 0, jeśli jest unikalny dla df1, 1, jeśli jest w obu ramkach danych. Następnie użyj tego, aby ograniczyć się do tego, co chcesz
źródło
źródło