판다의 데카르트 곱
두 개의 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]})
각 행에 대해 반복되는 키가있는 경우 SQL 에서처럼 병합을 사용하여 카티 전 곱을 생성 할 수 있습니다.
from pandas import DataFrame, merge
df1 = DataFrame({'key':[1,1], 'col1':[1,2],'col2':[3,4]})
df2 = DataFrame({'key':[1,1], 'col3':[5,6]})
merge(df1, df2,on='key')[['col1', 'col2', 'col3']]
산출:
col1 col2 col3
0 1 3 5
1 1 3 6
2 2 4 5
3 2 4 6
문서는 여기를 참조하십시오 : http://pandas.pydata.org/pandas-docs/stable/merging.html#brief-primer-on-merge-methods-relational-algebra
pd.MultiIndex.from_product
그렇지 않으면 비어있는 데이터 프레임에서 인덱스로 사용 하고 인덱스를 재설정하면 완료됩니다.
a = [1, 2, 3]
b = ["a", "b", "c"]
index = pd.MultiIndex.from_product([a, b], names = ["a", "b"])
pd.DataFrame(index = index).reset_index()
밖:
a b
0 1 a
1 1 b
2 1 c
3 2 a
4 2 b
5 2 c
6 3 a
7 3 b
8 3 c
이것은 코드 골프 대회에서 이기지 못하고 이전 답변에서 차용하지만 키가 추가되는 방법과 조인이 작동하는 방법을 명확하게 보여줍니다. 이렇게하면 목록에서 2 개의 새 데이터 프레임이 생성 된 다음 데카르트 곱을 수행 할 키가 추가됩니다.
내 사용 사례는 목록에서 매주 모든 상점 ID 목록이 필요하다는 것입니다. 그래서 저는 제가 갖고 싶었던 모든 주 목록을 만든 다음 매핑하려는 모든 상점 ID 목록을 만들었습니다.
내가 선택한 병합은 왼쪽이지만이 설정에서 의미 상 내부와 동일합니다. 병합에 대한 문서에서 이를 확인할 수 있습니다.이 문서 에서는 키 조합이 두 테이블에 두 번 이상 나타나는 경우 카티 전 곱을 수행한다고 설명합니다.
days = pd.DataFrame({'date':list_of_days})
stores = pd.DataFrame({'store_id':list_of_stores})
stores['key'] = 0
days['key'] = 0
days_and_stores = days.merge(stores, how='left', on = 'key')
days_and_stores.drop('key',1, inplace=True)
이것에 필요한 최소한의 코드. 데카르트 병합에 공통 '키'를 생성하여 두 가지를 병합합니다.
df1['key'] = 0
df2['key'] = 0
df_cartesian = df1.merge(df2, how='outer')
대안으로 itertools : itertools.product
에서 제공하는 데카르트 곱을 사용 하면 임시 키를 만들거나 색인을 수정하지 않아도됩니다.
import numpy as np
import pandas as pd
import itertools
def cartesian(df1, df2):
rows = itertools.product(df1.iterrows(), df2.iterrows())
df = pd.DataFrame(left.append(right) for (_, left), (_, right) in rows)
return df.reset_index(drop=True)
빠른 테스트 :
In [46]: a = pd.DataFrame(np.random.rand(5, 3), columns=["a", "b", "c"])
In [47]: b = pd.DataFrame(np.random.rand(5, 3), columns=["d", "e", "f"])
In [48]: cartesian(a,b)
Out[48]:
a b c d e f
0 0.436480 0.068491 0.260292 0.991311 0.064167 0.715142
1 0.436480 0.068491 0.260292 0.101777 0.840464 0.760616
2 0.436480 0.068491 0.260292 0.655391 0.289537 0.391893
3 0.436480 0.068491 0.260292 0.383729 0.061811 0.773627
4 0.436480 0.068491 0.260292 0.575711 0.995151 0.804567
5 0.469578 0.052932 0.633394 0.991311 0.064167 0.715142
6 0.469578 0.052932 0.633394 0.101777 0.840464 0.760616
7 0.469578 0.052932 0.633394 0.655391 0.289537 0.391893
8 0.469578 0.052932 0.633394 0.383729 0.061811 0.773627
9 0.469578 0.052932 0.633394 0.575711 0.995151 0.804567
10 0.466813 0.224062 0.218994 0.991311 0.064167 0.715142
11 0.466813 0.224062 0.218994 0.101777 0.840464 0.760616
12 0.466813 0.224062 0.218994 0.655391 0.289537 0.391893
13 0.466813 0.224062 0.218994 0.383729 0.061811 0.773627
14 0.466813 0.224062 0.218994 0.575711 0.995151 0.804567
15 0.831365 0.273890 0.130410 0.991311 0.064167 0.715142
16 0.831365 0.273890 0.130410 0.101777 0.840464 0.760616
17 0.831365 0.273890 0.130410 0.655391 0.289537 0.391893
18 0.831365 0.273890 0.130410 0.383729 0.061811 0.773627
19 0.831365 0.273890 0.130410 0.575711 0.995151 0.804567
20 0.447640 0.848283 0.627224 0.991311 0.064167 0.715142
21 0.447640 0.848283 0.627224 0.101777 0.840464 0.760616
22 0.447640 0.848283 0.627224 0.655391 0.289537 0.391893
23 0.447640 0.848283 0.627224 0.383729 0.061811 0.773627
24 0.447640 0.848283 0.627224 0.575711 0.995151 0.804567
메소드 체인 사용 :
product = (
df1.assign(key=1)
.merge(df2.assign(key=1), on="key")
.drop("key", axis=1)
)
map
그리고 zip
이해에서
DataFrame([
d1 + d2
for d1 in zip(*map(df1.get, df1))
for d2 in zip(*map(df2.get, df2))
], columns=df1.columns.append(df2.columns))
col1 col2 col3
0 1 3 5
1 1 3 6
2 2 4 5
3 2 4 6
If you have no overlapping columns, don't want to add one, and the indices of the data frames can be discarded, this may be easier:
df1.index[:] = df2.index[:] = 0
df_cartesian = df1.join(df2, how='outer')
df_cartesian.index[:] = range(len(df_cartesian))
I find using pandas MultiIndex to be the best tool for the job. If you have a list of lists lists_list
, call pd.MultiIndex.from_product(lists_list)
and iterate over the result (or use it in DataFrame index).
참고URL : https://stackoverflow.com/questions/13269890/cartesian-product-in-pandas
'Development Tip' 카테고리의 다른 글
여러 요소 컬렉션을 결합하는 우아한 방법? (0) | 2020.10.11 |
---|---|
정적 위치와 상대 위치의 차이점 (0) | 2020.10.11 |
PowerMockito.whenNew () 사용이 조롱되지 않고 원래 메서드가 호출 됨 (0) | 2020.10.11 |
Java 8 및 Java 9에서 서명되지 않은 정수를 사용하는 방법은 무엇입니까? (0) | 2020.10.11 |
명령 줄 인터페이스로 Clojure 앱을 구축하고 계십니까? (0) | 2020.10.11 |