Mam następujący DataFrame, w którym jedna z kolumn jest obiektem (komórka typu listy):
df=pd.DataFrame({'A':[1,2],'B':[[1,2],[1,2]]})
df
Out[458]:
A B
0 1 [1, 2]
1 2 [1, 2]
Oczekiwany wynik to:
A B
0 1 1
1 1 2
3 2 1
4 2 2
Co mam zrobić, żeby to osiągnąć?
Powiązane pytanie
pandy: gdy zawartość komórki jest listą, utwórz wiersz dla każdego elementu na liście
Dobre pytanie i odpowiedź, ale obsługuj tylko jedną kolumnę z listą (w mojej odpowiedzi funkcja samoobrony będzie działać dla wielu kolumn, również akceptowana odpowiedź to użycie najbardziej czasochłonnej apply
, co nie jest zalecane, sprawdź więcej informacji Kiedy powinienem kiedykolwiek chcieć używać pand Apply () w moim kodzie? )
Odpowiedzi:
Wiem, że
object
kolumnytype
utrudniają konwersję danych za pomocąpandas
funkcji. Kiedy otrzymałem takie dane, pierwszą rzeczą, która przyszła mi do głowy, było „spłaszczenie” lub odkształcenie kolumn.Używam
pandas
ipython
funkcji dla tego typu pytań. Jeśli martwisz się o szybkość powyższych rozwiązań, sprawdź odpowiedź użytkownika3483203 , ponieważ używanumpy
i przez większość czasunumpy
jest szybsza. PolecamCpython
inumba
jeśli liczy się szybkość.Metoda 0 [pandy> = 0,25]
Zaczynając od pand 0,25 , jeśli chcesz rozbić tylko jedną kolumnę, możesz użyć
pandas.DataFrame.explode
funkcji:Biorąc pod uwagę ramkę danych z pustą
list
lubNaN
w kolumnie. Pusta lista nie spowoduje problemu, aleNaN
wolę należy wypełnićlist
Metoda 1
apply + pd.Series
(łatwa do zrozumienia, ale pod względem wydajności nie jest zalecana).Metoda 2
Używając
repeat
zDataFrame
konstruktorem, ponownie utwórz ramkę danych (dobra pod względem wydajności, niezbyt dobra w wielu kolumnach)Na przykład metoda 2.1 oprócz A mamy A.1 ..... An Jeśli nadal używamy powyższej metody ( Metoda 2 ), trudno jest nam odtworzyć kolumny jedna po drugiej.
Rozwiązanie:
join
albomerge
zindex
po „unnest” pojedynczych kolumnJeśli chcesz, aby kolejność kolumn była dokładnie taka sama jak poprzednio, dodaj
reindex
na końcu.Metoda 3:
Odtwórz plik
list
Jeśli więcej niż dwie kolumny, użyj
Metoda 4
przy użyciu
reindex
lubloc
Metoda 5,
gdy lista zawiera tylko unikalne wartości:
Metoda 6
stosując
numpy
o wysokiej wydajności:Metoda 7
wykorzystująca funkcję podstawową
itertools
cycle
ichain
: Czyste rozwiązanie w Pythonie dla zabawyUogólnianie na wiele kolumn
Funkcja samoobrony:
Unnesting kolumnowy
Cała powyższa metoda mówi o pionowym rozebraniu i eksplozji.Jeśli potrzebujesz rozłożyć listę w poziomie , Sprawdź
pd.DataFrame
konstruktoremZaktualizowana funkcja
Wyjście testowe
źródło
opcja 1
Jeśli wszystkie listy podrzędne w drugiej kolumnie mają tę samą długość,
numpy
wydajną opcją może być tutaj:Opcja 2
Jeśli podlisty mają różną długość, potrzebny jest dodatkowy krok:
Opcja 3
Zrobiłem próbę uogólnienia tego, aby spłaszczyć
N
kolumny iM
kolumny kafelkowe , później popracuję nad poprawieniem wydajności:Funkcje
Czasy
Występ
źródło
df.explode
metodą.Rozbijanie kolumny podobnej do listy zostało znacznie uproszczone w pandach 0,25 dzięki dodaniu
explode()
metody:Na zewnątrz:
źródło
Jedną z alternatyw jest zastosowanie przepisu siatki mesh na rzędach kolumn, aby odłączyć:
Wynik
źródło
Moje 5 centów:
i kolejny 5
oba skutkują tym samym
źródło
Konfiguracja problemu
Załóżmy, że istnieje wiele kolumn z obiektami o różnej długości
Gdy długości są takie same, łatwo jest założyć, że poszczególne elementy pokrywają się i powinny być ze sobą „zapięte”.
Jednak założenie to staje się kwestionowane, gdy widzimy obiekty o różnej długości, czy powinniśmy "zipować", jeśli tak, to jak sobie poradzimy z nadmiarem jednego z obiektów. A może chcemy iloczynu wszystkich obiektów. To szybko się rozwinie, ale może być tym, czego chcemy.
LUB
Funkcja
Ta funkcja z wdziękiem obsługuje parametr
zip
lubproduct
opiera się na nim i przyjmujezip
zgodnie z długością najdłuższego obiektu zzip_longest
Zapinane
Produkt
Nowa konfiguracja
Trochę inny przykład
Zapinane
Produkt
źródło
Ponieważ zwykle długość podlist jest różna, a łączenie / scalanie jest znacznie bardziej kosztowne obliczeniowo. Ponownie przetestowałem tę metodę dla podlist o innej długości i bardziej normalnych kolumn.
MultiIndex powinien być również łatwiejszym sposobem pisania i ma prawie takie same wyniki jak numpy sposób.
O dziwo, w moim zrozumieniu implementacji sposób ma najlepszą wydajność.
Występ
Względny czas każdej metody
źródło
Uogólniłem nieco problem, aby można go było zastosować do większej liczby kolumn.
Podsumowanie tego, co robi moje rozwiązanie:
Kompletny przykład:
Właściwa eksplozja odbywa się w 3 liniach. Reszta to kosmetyki (wielokolumnowa eksplozja, obsługa ciągów znaków zamiast list w kolumnie eksplozji, ...).
Kredyty dla za odpowiedź WeNYoBena
źródło
Coś całkiem niezalecane (przynajmniej działa w tym przypadku):
concat
+sort_index
+iter
+apply
+next
.Teraz:
Jest:
Jeśli zależy Ci na indeksie:
Teraz:
Jest:
źródło
Jakieś opinie na temat tej metody, o których myślałem? czy też wykonywanie operacji concat i melt jest uważane za zbyt „kosztowne”?
źródło
Mam inny dobry sposób na rozwiązanie tego problemu, gdy masz więcej niż jedną kolumnę do wybuchu.
Chcę wysadzić kolumny B i C. Najpierw eksploduję B, drugie C. Następnie upuszczam B i C z oryginalnego df. Następnie zrobię przyłączenie indeksu do 3 dfs.
źródło
źródło
źródło
W moim przypadku z więcej niż jedną kolumną do rozbicia i ze zmiennymi długościami dla tablic, które muszą być niezagospodarowane.
Skończyło się na
explode
dwukrotnym zastosowaniu nowej funkcji pandy 0.25 , a następnie usunięciu wygenerowanych duplikatów i robi swoje!źródło