Mam dwie pandy dataframe:
from pandas import DataFrame
df1 = DataFrame({'col1':[1,2],'col2':[3,4]})
df2 = DataFrame({'col3':[5,6]})
Jaka jest najlepsza praktyka, aby uzyskać ich produkt kartezjański (oczywiście bez pisania tego wyraźnie tak jak ja)?
#df1, df2 cartesian product
df_cartesian = DataFrame({'col1':[1,2,1,2],'col2':[3,4,3,4],'col3':[5,5,6,6]})
Użyj
pd.MultiIndex.from_product
jako indeksu w pustej ramce danych, a następnie zresetuj jej indeks i gotowe.na zewnątrz:
źródło
df1.col1
idf.col2
).from_product
można go było wykorzystać do tego problemu.To nie wygra zawodów w golfie kodowym i zapożycza z poprzednich odpowiedzi - ale wyraźnie pokazuje, w jaki sposób klucz jest dodawany i jak działa łączenie. Tworzy to 2 nowe ramki danych z list, a następnie dodaje klucz do wykonania iloczynu kartezjańskiego.
Moim przypadkiem użycia było to, że potrzebowałem listy wszystkich identyfikatorów sklepów na każdy tydzień na mojej liście. Utworzyłem więc listę wszystkich tygodni, które chciałem mieć, a następnie listę wszystkich identyfikatorów sklepów, według których chciałem je zmapować.
Scalanie, które wybrałem, pozostawiłoby, ale byłoby semantycznie takie same jak wewnętrzne w tej konfiguracji. Możesz to zobaczyć w dokumentacji dotyczącej scalania , która stwierdza, że wykonuje iloczyn kartezjański, jeśli kombinacja klawiszy pojawia się więcej niż raz w obu tabelach - tak właśnie skonfigurowaliśmy.
źródło
days_and_stores = pd.merge(days.assign(key=0), stores.assign(key=0), on='key').drop('key', axis=1)
Do tego potrzebny jest minimalny kod. Utwórz wspólny „klucz” do kartezjańskiego połączenia tych dwóch elementów:
źródło
df_cartesian = df_cartesian.drop(columns=['key'])
posprzątać na koniecW przypadku łączenia metod:
źródło
Alternatywnie można polegać na produkcie kartezjańskim dostarczanym przez itertools:
itertools.product
który pozwala uniknąć tworzenia tymczasowego klucza lub modyfikowania indeksu:Szybki test:
źródło
Jeśli nie masz nakładających się kolumn, nie chcesz ich dodawać, a indeksy ramek danych można odrzucić, może to być łatwiejsze:
źródło
TypeError: '<class 'pandas.core.index.Int64Index'>' does not support mutable operations.
mogę to obejść, dodając, index=[0,0]
do definicji ramki danych.df1 = df1.set_index([[0]*len(df1)]))
(i podobnie dladf2
).Oto funkcja pomocnicza do wykonania prostego iloczynu kartezjańskiego z dwiema ramkami danych. Logika wewnętrzna obsługuje użycie klucza wewnętrznego i pozwala uniknąć zniekształcania kolumn, które mają nazwę „klucz” z dowolnej strony.
przedstawia:
źródło
Można zacząć biorąc iloczyn kartezjański
df1.col1
idf2.col3
, a następnie połączyć z powrotemdf1
dostaćcol2
.Oto ogólna funkcja iloczynu kartezjańskiego, która pobiera słownik list:
Zastosuj jako:
źródło
Możesz użyć numpy, ponieważ może być szybszy. Załóżmy, że masz dwie następujące serie:
Ty po prostu potrzebujesz,
źródło
Uważam, że używanie pand MultiIndex jest najlepszym narzędziem do pracy. Jeśli masz listę list
lists_list
, wywołajpd.MultiIndex.from_product(lists_list)
i iteruj po wyniku (lub użyj go w indeksie DataFrame).źródło