2017-10-09 6 views
2

두 개의 DataFrames가 있습니다. 하나는 특정 시간과 날짜 (df_1)에 해당하는 값 집합입니다. 다른 하나는 특정 날짜 (df_2)에 해당하는 값 집합입니다. 날짜에 대한 df_2의 값이 해당 날짜의 df_1에 적용되도록 이러한 DataFrames를 병합하고 싶습니다.DataFrames를 병합하여 * dates *에 해당하는 값이 다른 날짜의 모든 * times *에 적용되도록하는 방법은 무엇입니까?

그래서, 여기에 df_1입니다 : 여기

|DatetimeIndex   |value_1| 
|-----------------------|-------| 
|2015-07-18 13:53:33.280|10  | 
|2015-07-18 15:43:30.111|11  | 
|2015-07-19 13:54:03.330|12  | 
|2015-07-20 13:52:13.350|13  | 
|2015-07-20 16:10:01.901|14  | 
|2015-07-20 16:50:55.020|15  | 
|2015-07-21 13:56:03.126|16  | 
|2015-07-22 13:53:51.747|17  | 
|2015-07-22 19:45:14.647|18  | 
|2015-07-23 13:53:29.346|19  | 
|2015-07-23 20:00:30.100|20  | 

및 것은 df_2입니다 :

|DatetimeIndex|value_2| 
|-------------|-------| 
|2015-07-18 |100 | 
|2015-07-19 |200 | 
|2015-07-20 |300 | 
|2015-07-21 |400 | 
|2015-07-22 |500 | 
|2015-07-23 |600 | 

나는이처럼 그들을 병합 할 :

|DatetimeIndex   |value_1|value_2| 
|-----------------------|-------|-------| 
|2015-07-18 00:00:00.000|NaN |100 | 
|2015-07-18 13:53:33.280|10.0 |100 | 
|2015-07-18 15:43:30.111|11.0 |100 | 
|2015-07-19 00:00:00.000|NaN |200 | 
|2015-07-19 13:54:03.330|12.0 |200 | 
|2015-07-20 00:00:00.000|NaN |300 | 
|2015-07-20 13:52:13.350|13.0 |300 | 
|2015-07-20 16:10:01.901|14.0 |300 | 
|2015-07-20 16:50:55.020|15.0 |300 | 
|2015-07-21 00:00:00.000|NaN |400 | 
|2015-07-21 13:56:03.126|16.0 |400 | 
|2015-07-22 00:00:00.000|NaN |500 | 
|2015-07-22 13:53:51.747|17  |500 | 
|2015-07-22 19:45:14.647|18  |500 | 
|2015-07-23 00:00:00.000|NaN |600 | 
|2015-07-23 13:53:29.346|19  |600 | 
|2015-07-23 20:00:30.100|20  |600 | 

는 그래서, value_2가 전반에 걸쳐 존재

일.

어떤 종류의 병합이 호출됩니까? 어떻게 할 수 있습니까? 다음과 같이 DataFrames에 대한

코드는 다음과 같습니다

import pandas as pd 

df_1 = pd.DataFrame(
    [ 
     [pd.Timestamp("2015-07-18 13:53:33.280"), 10], 
     [pd.Timestamp("2015-07-18 15:43:30.111"), 11], 
     [pd.Timestamp("2015-07-19 13:54:03.330"), 12], 
     [pd.Timestamp("2015-07-20 13:52:13.350"), 13], 
     [pd.Timestamp("2015-07-20 16:10:01.901"), 14], 
     [pd.Timestamp("2015-07-20 16:50:55.020"), 15], 
     [pd.Timestamp("2015-07-21 13:56:03.126"), 16], 
     [pd.Timestamp("2015-07-22 13:53:51.747"), 17], 
     [pd.Timestamp("2015-07-22 19:45:14.647"), 18], 
     [pd.Timestamp("2015-07-23 13:53:29.346"), 19], 
     [pd.Timestamp("2015-07-23 20:00:30.100"), 20] 
    ], 
    columns = [ 
     "datetime", 
     "value_1" 
    ] 
) 
df_1.index = df_1["datetime"] 
del df_1["datetime"] 
df_1.index = pd.to_datetime(df_1.index.values) 

df_2 = pd.DataFrame(
    [ 
     [pd.Timestamp("2015-07-18 00:00:00"), 100], 
     [pd.Timestamp("2015-07-19 00:00:00"), 200], 
     [pd.Timestamp("2015-07-20 00:00:00"), 300], 
     [pd.Timestamp("2015-07-21 00:00:00"), 400], 
     [pd.Timestamp("2015-07-22 00:00:00"), 500], 
     [pd.Timestamp("2015-07-23 00:00:00"), 600] 
    ], 
    columns = [ 
     "datetime", 
     "value_2" 
    ] 
) 
df_2 
df_2.index = df_2["datetime"] 
del df_2["datetime"] 
df_2.index = pd.to_datetime(df_2.index.values) 

답변

3

솔루션
이 둘의 조합 인 새로운 인덱스를 구축합니다. 이어서 자기 설명되어야 둘의 조합을 취하는 reindex의 조합 map

idx = df_1.index.union(df_2.index) 

df_1.reindex(idx).assign(value_2=idx.floor('D').map(df_2.value_2.get)) 

         value_1 value_2 
2015-07-18 00:00:00.000  NaN  100 
2015-07-18 13:53:33.280  10.0  100 
2015-07-18 15:43:30.111  11.0  100 
2015-07-19 00:00:00.000  NaN  200 
2015-07-19 13:54:03.330  12.0  200 
2015-07-20 00:00:00.000  NaN  300 
2015-07-20 13:52:13.350  13.0  300 
2015-07-20 16:10:01.901  14.0  300 
2015-07-20 16:50:55.020  15.0  300 
2015-07-21 00:00:00.000  NaN  400 
2015-07-21 13:56:03.126  16.0  400 
2015-07-22 00:00:00.000  NaN  500 
2015-07-22 13:53:51.747  17.0  500 
2015-07-22 19:45:14.647  18.0  500 
2015-07-23 00:00:00.000  NaN  600 
2015-07-23 13:53:29.346  19.0  600 
2015-07-23 20:00:30.100  20.0  600 

설명

  • 를 사용한다. 그러나 유니온을 사용할 때 자동으로 정렬 된 인덱스를 얻습니다. 그게 편리합니다!
  • df_1을 색인의 새롭고 향상된 통합으로 다시 색인하면 일부 색인 값은 df_1의 색인에 나타나지 않습니다. 다른 매개 변수를 지정하지 않으면 이전에 존재하지 않는 색인의 열 값은 np.nan이되며 이는 우리가 수행 한 것입니다.
  • 난 열을 추가하려면 assign을 사용합니다.
    • 나는 그것이 청소기 생각
    • 그것은 pd.DatetimeIndex 인의 특성을 유지하면서
  • idx.floor('D') 나에게 일을 제공 내가 잘
  • 그것은 파이프 라인과 함께 일하고 있어요 dataframe을 덮어 쓰지 않습니다. 이 바로 뒤에 map 수 있습니다.
  • pd.Index.map 내가 df_2 여러 열이
    한다고 가정 코멘트에 (내가 좋아하는) dict.get처럼 많이 느낀다 df_2.value_2.get

응답을 패스 호출

  • 합니다. 우리는 대신

    df_1.join(df_2.loc[idx.date].set_index(idx), how='outer') 
    
             value_1 value_2 
    2015-07-18 00:00:00.000  NaN  100 
    2015-07-18 13:53:33.280  10.0  100 
    2015-07-18 15:43:30.111  11.0  100 
    2015-07-19 00:00:00.000  NaN  200 
    2015-07-19 13:54:03.330  12.0  200 
    2015-07-20 00:00:00.000  NaN  300 
    2015-07-20 13:52:13.350  13.0  300 
    2015-07-20 16:10:01.901  14.0  300 
    2015-07-20 16:50:55.020  15.0  300 
    2015-07-21 00:00:00.000  NaN  400 
    2015-07-21 13:56:03.126  16.0  400 
    2015-07-22 00:00:00.000  NaN  500 
    2015-07-22 13:53:51.747  17.0  500 
    2015-07-22 19:45:14.647  18.0  500 
    2015-07-23 00:00:00.000  NaN  600 
    2015-07-23 13:53:29.346  19.0  600 
    2015-07-23 20:00:30.100  20.0  600 
    

    이처럼 보일 수 join를 사용할 수있는 더 나은 짧은 것을 대답합니다. 그러나 단일 열의 경우에는 더 느립니다. 꼭 멀티 컬럼 케이스에 사용하십시오.

    %timeit df_1.reindex(idx).assign(value_2=idx.floor('D').map(df_2.value_2.get)) 
    %timeit df_1.join(df_2.loc[idx.date].set_index(idx), how='outer') 
    
    1.56 ms ± 69 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 
    2.38 ms ± 591 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 
    
  • +0

    아하 이것은 굉장합니다. 상세한 설명을 많이 주셔서 감사합니다. 'flood ('D') '를 사용하는 것이 특히 유용했습니다. 약간 어색한 후속 질문 (대답이 간단하다면) : 실제로 각 DataFrames에 * 많은 * 값이 있다고 가정 해 봅시다. 각 변수를 "하드 코딩"하지 않고 이러한 방식으로 병합 할 수 있습니까? – BlandCorporation

    +0

    예! 대답을 업데이트 할 시간을주세요. – piRSquared

    +0

    안녕하세요. 추가 세부 정보를 다시 보내 주셔서 감사합니다. 효율성 정보를 보는 것도 좋습니다. – BlandCorporation