공통 날짜 인덱스에서 두 개의 데이터 프레임 (PRIM_recs 및 SECO_recs)을 병합하고 싶습니다.
PRIM_recs =
Hsig Thsig Hrms Hmax Tc Tz
1976-10-31 15:00:00 0.93 8.21 0.64 1.75 2.82 5.42...
1976-11-01 03:00:00 1.34 6.08 0.93 2.11 3.14 4.56...
1976-11-01 15:00:00 1.39 6.01 0.99 2.40 2.80 4.38...
1976-11-02 03:00:00 1.30 6.35 0.93 2.18 3.24 4.91...
1976-11-02 15:00:00 1.31 9.91 0.91 2.18 3.36 6.71...
: : : : : : : : : :
2017-05-20 04:00:00 1.442527 7.407674 1.050540 2.61 5.868847 5.891295...
2017-05-20 04:30:00 1.555761 6.361763 1.108141 3.16 5.758905 5.770841...
2017-05-20 05:00:00 1.563837 7.925315 1.143206 2.31 6.160781 6.181728...
2017-05-20 05:30:00 1.637766 7.488912 1.154951 2.66 5.647312 5.672689...
2017-05-20 06:00:00 1.622043 7.154768 1.146905 2.55 5.679639 5.714273...
SECO_recs =
Spc
1976-10-31 15:00:00 [0.0124, 0.0096, 0.0325, 0.1562, 0.4494, 0.738...
1976-11-01 03:00:00 [0.0254, 0.0299, 0.0273, 0.1229, 0.596, 0.9833...
1976-11-01 15:00:00 [0.0226, 0.0236, 0.0269, 0.085, 0.4163, 0.8011...
1976-11-02 03:00:00 [0.0132, 0.0154, 0.0172, 0.1336, 0.4743, 0.694...
1976-11-02 15:00:00 [0.0124, 0.0169, 0.028, 0.5028, 1.4503, 1.6055...
: : : : : : : : : :
2017-05-20 04:00:00 [5.374061e-13, 1.2720002e-06, 0.00052255474, 0...
2017-05-20 04:30:00 [1.2021946e-12, 3.3477074e-06, 0.0014435094, 0...
2017-05-20 05:00:00 [1.2236685e-13, 5.018357e-07, 0.00023753957, 0...
2017-05-20 05:30:00 [3.5527579e-13, 1.1004944e-06, 0.0005480177, 0...
2017-05-20 06:00:00 [4.968573e-13, 1.4969078e-06, 0.00065009575, 0...
다음 문을 사용하여 병합을 수행합니다.
# Merge PRIM data with SECO data on common dates
df_PRIM_SECO = pd.merge(PRIM_recs, SECO_recs, left_index=True, right_index=True)
이렇게하면 병합 된 데이터 프레임 (df_PRIM_SECO)이 제공 되지만이 df에는 여러 개의 중복 행이 포함되어 있습니다 !
PRIM 길이 = 364229
SECO 길이 = 364228
병합 된 길이 = 364271
이 문제를 해결하기 위해 현재 다음 진술을 포함합니다.
# Need to drop any duplicate index values that resulted from the merge
df_PRIM_SECO = df_PRIM_SECO.loc[~df_PRIM_SECO.index.duplicated(keep='first')]
이것은 필요한 데이터 프레임을 제공합니다 (중복 제외)!
PRIM 길이 = 364229
SECO 길이 = 364228
병합 된 길이 = 364202
df_PRIM_SECO의 행 수가 적은 경우 (PRIM_recs 또는 SECO_recs보다) 병합에 의해 생략 된 일부 비 공통 날짜가있는 원래 데이터 프레임에서 발생합니다.
내 질문은 :
이제 원하는 결과를 얻었지만 merge 문이 중복 행을 생성하는 이유는 무엇입니까?
TLDR : 병합시 Pandas는 가능한 모든 중복 키 조합을 자동으로 병합합니다.
먼저 내부 병합 (기본 how
매개 변수)을 수행합니다 . 여기서 키 (귀하의 경우 인덱스)가 두 세트에 모두 없으면 최종 병합에서 제외됩니다.
여기서는 타임 스탬프 인덱스가 아니라 단순성을 위해 문자열이있는 열을 키로 병합한다고 가정 해 보겠습니다. 예를 들면
d1 = pd.DataFrame({'A': ['a', 'b'], 'n1': [1,2]})
d2 = pd.DataFrame({'A': ['b', 'c'], 'n2': [8,9]})
pd.merge(d1,d2, on='A')
생산하다
A n1 n2
0 b 2 8
보시다시피 'b'
두 열에 상주하는 유일한 키이므로 병합시 해당 인스턴스 만 유지합니다. 우리가 변경 한 경우 따라서 dataframe의 결과로 크기는 1이었다 d2
약간
d1 = pd.DataFrame({'A': ['a', 'b'], 'n1': [1,2]})
d2 = pd.DataFrame({'A': ['b', 'b'], 'n2': [8,9]}) # change instance 'c' to 'b'
pd.merge(d1,d2, on='A')
병합은 대신 생성
A n1 n2
0 b 2 8
1 b 2 9
차종은 2 경우, 감지 'b'
에 'd2'
따라서 2 개 인스턴스 'b'
병합 후. 하지만 이제 우리가 d1
약간 변했다면
d1 = pd.DataFrame({'A': ['a', 'b', 'b'], 'n1': [1,2,3]}) # added another instance of b
d2 = pd.DataFrame({'A': ['b', 'b'], 'n2': [8,9]})
좋습니다. 동일한 논리 'b'
에 따라 각 데이터 프레임에 의 2 개의 인스턴스가 있고 내부 병합을 수행하고 있으므로 'b'
병합 후에는 2 개의 인스턴스가 있어야합니다 .
'b'
이제 각 인스턴스를의 모든 인스턴스에서 병합해야하므로 이는 올바르지 않습니다 'b'
. 보여주기 위해
pd.merge(d1,d2, on='A')
A n1 n2
0 b 2 8
1 b 2 9
2 b 3 8
3 b 3 9
이제 크기는 4입니다. 검사시 'b' 2
와 'b' 8
뿐만 아니라 'b' 9
. 이것은 또한 'b' 3
. d1
및 의 크기가 d2
각각 3과 2 인 것을 확인하면 둘 다보다 큰 크기의 데이터 프레임을 얻었 습니다 . 따라서 이것은 병합 전에 카테고리의 여러 인스턴스가 두 데이터 프레임에 있기 때문에 발생합니다. 언급했듯이 병합 후 중복 된 값을 삭제하여 크기 문제를 해결합니다. 복제 된 첫 번째 값을 유지하고 나머지는 버립니다. 이 예에서는
pd.merge(d1,d2, on='A').drop_duplicates(subset='A', keep='first')
A n1 n2
0 b 2 8
보시다시피 첫 번째 병합 예제에서 동일한 출력을 반환합니다. 병합 후 키에 대한 이러한 중복으로 인해 출력되는 데이터 프레임의 크기가 더 커지는 것이 불편할 수 있습니다.
이 느낌을 완화하기 위해 대신 병합 전에 중복 값을 삭제할 수 있습니다. 'b'
병합을 수행하는 경우 추가 된 인스턴스가있는 데이터 프레임 사용
d1 = pd.DataFrame({'A': ['a', 'b', 'b'], 'n1': [1,2,3]}).drop_duplicates(subset='A', keep='first')
d2 = pd.DataFrame({'A': ['b', 'b'], 'n2': [8,9]})
pd.merge(d1,d2, on='A')
위에서 설명한 원래 두 번째 병합과 동일한 출력을 얻습니다.
A n1 n2
0 b 2 8
1 b 2 9
마지막으로 두 데이터 프레임에서 중복 항목을 삭제하면 원래 첫 번째 병합 출력을 얻습니다.
d1 = pd.DataFrame({'A': ['a', 'b', 'b'], 'n1': [1,2,3]}).drop_duplicates(subset='A', keep='first')
d2 = pd.DataFrame({'A': ['b', 'b'], 'n2': [8,9]}).drop_duplicates(subset='A', keep='first')
pd.merge(d1,d2, on='A')
A n1 n2
0 b 2 8
그렇다면 merge 문이 중복 행을 생성하는 이유는 무엇입니까? 표시된 것처럼 키 매핑과 관련이 있습니다. 병합시 Pandas는 가능한 모든 중복 키 조합을 자동으로 병합합니다. 이렇게하지 않으면 훨씬 덜 유연한 작업이 될 것입니다. 대신 병합 이전 (또는 이후)을 지정하여 중복 항목을 삭제하여 이런 일이 발생하지 않도록 할 수 있습니다.
중복 키 값이 많은 더 큰 데이터 프레임에서 가능한 모든 조합을 만드는이 작업은 결과 데이터 프레임을 빠르게 확장 할 수 있습니다 (시도하고 및 'b'
둘 다에 인스턴스를 몇 개 더 추가 ). 그러나 귀하의 경우에는 각 데이터 프레임에 몇 개의 중복 만있는 것 같습니다. 더 많은 중복이 있다면 병합 전에 중복을 삭제하는 것이 좋지만 귀하의 경우에는 큰 문제가 아닌 것 같습니다.d1
d2
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다