У меня есть два фрейма данных pandas:
from pandas import DataFrame
df1 = DataFrame({'col1':[1,2],'col2':[3,4]})
df2 = DataFrame({'col3':[5,6]})
Как лучше всего получить их декартово произведение (конечно, не написав его явно, как я)?
#df1, df2 cartesian product
df_cartesian = DataFrame({'col1':[1,2,1,2],'col2':[3,4,3,4],'col3':[5,5,6,6]})
Используйте
pd.MultiIndex.from_product
в качестве индекса в пустом фрейме данных, затем сбросьте его индекс, и все готово.вне:
источник
df1.col1
иdf.col2
).from_product
это можно использовать для решения этой проблемы.Это не выиграет соревнование по гольфу кода и заимствует из предыдущих ответов, но ясно показывает, как добавляется ключ и как работает соединение. Это создает 2 новых фрейма данных из списков, а затем добавляет ключ для декартового произведения.
Мой вариант использования заключался в том, что мне нужен был список всех идентификаторов магазинов на каждую неделю в моем списке. Итак, я составил список всех недель, которые я хотел провести, а затем список всех идентификаторов магазинов, с которыми я хотел сопоставить их.
Я выбрал слияние слева, но семантически оно будет таким же, как внутреннее в этой настройке. Вы можете увидеть это в документации по слиянию , в которой говорится, что это декартово произведение, если комбинация клавиш встречается более одного раза в обеих таблицах - что мы и настроили.
источник
days_and_stores = pd.merge(days.assign(key=0), stores.assign(key=0), on='key').drop('key', axis=1)
Минимальный код, необходимый для этого. Создайте общий "ключ" для декартового слияния двух:
источник
df_cartesian = df_cartesian.drop(columns=['key'])
очистить в концеС цепочкой методов:
источник
В качестве альтернативы можно полагаться на декартово произведение, предоставляемое itertools :
itertools.product
, что позволяет избежать создания временного ключа или изменения индекса:Быстрый тест:
источник
Если у вас нет перекрывающихся столбцов, вы не хотите их добавлять, а индексы кадров данных можно отбросить, это может быть проще:
источник
TypeError: '<class 'pandas.core.index.Int64Index'>' does not support mutable operations.
я могу обойти это, добавив, index=[0,0]
в определение фрейма данных.df1 = df1.set_index([[0]*len(df1)]))
(и аналогично дляdf2
).Вот вспомогательная функция для выполнения простого декартова произведения с двумя фреймами данных. Внутренняя логика обрабатывает использование внутреннего ключа и избегает искажения любых столбцов, которые случайно названы "ключом" с любой стороны.
показывает:
источник
Вы можете начать с декартова произведения на
df1.col1
иdf2.col3
, а затем снова слить в,df1
чтобы получитьcol2
.Вот общая декартова функция произведения, которая принимает словарь списков:
Применить как:
источник
Вы можете использовать numpy, так как это может быть быстрее. Предположим, у вас есть две следующих серии:
Вам просто нужно,
источник
Я считаю использование pandas MultiIndex лучшим инструментом для работы. Если у вас есть список списков
lists_list
, вызовитеpd.MultiIndex.from_product(lists_list)
и переберите результат (или используйте его в индексе DataFrame).источник