簡體   English   中英

如何在索引和列上合並兩個數據框

[英]how to merge two dataframes on both indexes and columns

這是問題所在:我知道如何在索引或列上合並兩個DataFrame ,但我無法在索引和列上合並它們。

我有兩個DataFrame ,我想將它們合並到索引(日期)和列id上。 我創建了一些示例數據來更好地解釋我的問題。

from datetime import date
import numpy as np
import pandas as pd

np.random.seed(200)
dates = [date(2020, 1, 31), date(2020, 2, 28)]
a = {"id": ["A", "B"] * len(dates), "w": [.5, .5] * len(dates)}
b = {"id": ["B", "A"] * len(dates), "x": np.random.random(2 * len(dates))}

a = pd.DataFrame(a, index=dates * len(dates))
b = pd.DataFrame(b, index=dates * len(dates))

所需的 output:

           id    w         x
2020-01-31  A  0.5  0.226547
2020-02-28  B  0.5  0.947632
2020-01-31  A  0.5  0.428309
2020-02-28  B  0.5  0.594420

請注意,我正在尋找一個通用解決方案,其中ab不一定在id中包含相同的索引或元素。

IIUC,您可以使用set_index到 append 列,使用join ,然后像reset_index

print(a.set_index('id', append=True)\
       .join(b.set_index('id', append=True), how='outer')\
       .reset_index('id'))
           id    w         x
2020-01-31  A  0.5  0.947632
2020-02-28  B  0.5  0.226547
2020-01-31  B  0.5  0.594420
2020-02-28  A  0.5  0.428309

或與merge相反的方向:

print(a.reset_index()\
       .merge(b.reset_index(), on=['index', 'id'], how='outer')\
       .set_index('index'))
           id    w         x
index                       
2020-01-31  A  0.5  0.947632
2020-02-28  B  0.5  0.226547
2020-01-31  B  0.5  0.594420
2020-02-28  A  0.5  0.428309

為了確保這是您想要做的,讓我們假設 a 和 b 是這樣的,帶有另一個 id:

a = pd.DataFrame({"id": ["A", "B", 'B','A'] , "w": np.random.random(4)}, 
                 index=[date(2020, 1, 31), date(2020, 2, 28)]*2)
#           id         w
#2020-01-31  A  0.764141
#2020-02-28  B  0.002861
#2020-01-31  B  0.357424
#2020-02-28  A  0.909695

b = pd.DataFrame({"id": ["A", "B", 'C','A'], "x": np.random.random(4)}, 
                 index=[date(2020, 1, 31), date(2020, 2, 28)]*2)
#           id         x
#2020-01-31  A  0.456081
#2020-02-28  B  0.981803
#2020-01-31  C  0.867357
#2020-02-28  A  0.986028

那么使用join方法的結果是:

           id         w         x
2020-01-31  A  0.764141  0.456081
2020-01-31  B  0.357424       NaN
2020-01-31  C       NaN  0.867357
2020-02-28  A  0.909695  0.986028
2020-02-28  B  0.002861  0.981803

您可以簡單地使用b['w'] = a['w']添加一個新列。 這實際上是一個合並,而是一個從 a 到 b 的副本。

完整的代碼是:

from datetime import date
import numpy as np
import pandas as pd

np.random.seed(200)
ids = ["A", "B"]
dates = [date(2020, 1, 31), date(2020, 2, 28)]
a = {"id": ids * len(dates), "w": [.5, .5] * len(dates)}
b = {"id": ids * len(dates), "x": np.random.random(len(ids) * len(dates))}

a = pd.DataFrame(a, index=dates * len(dates))
b = pd.DataFrame(b, index=dates * len(dates))

b['w'] = a['w']
print(b)

編輯:獲得所需結果的其他方式(好吧,由於重復的“id”列,我不太確定)。 請告訴我兩個dataframe的id結構:

import pandas as pd

a = pandas.DataFrame([
    ['A', 0.5],
    ['B', 1],
    ['C', 1.5],
    ['D', 2.]],
    columns=['id', 'w'], 
    index=['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04'])
print(a)

b = pandas.DataFrame([
    ['A', 0.5],
    ['B', 1],
    ['C', 1.5],
    ['D', 2.]],
    columns=['id', 'x'], 
    index=['2020-01-02', '2020-01-03', '2020-01-04', '2020-01-05'])
print(b)

c = pandas.concat([a, b], axis=1)
print(c)

output:

           id    w
2020-01-01  A  0.5
2020-01-02  B  1.0
2020-01-03  C  1.5
2020-01-04  D  2.0
           id    x
2020-01-02  A  0.5
2020-01-03  B  1.0
2020-01-04  C  1.5
2020-01-05  D  2.0
             id    w   id    x
2020-01-01    A  0.5  NaN  NaN
2020-01-02    B  1.0    A  0.5
2020-01-03    C  1.5    B  1.0
2020-01-04    D  2.0    C  1.5
2020-01-05  NaN  NaN    D  2.0

使用基於 cumcount 的輔助列,為索引命名以使其更容易合並索引:

a['helper'] = a.groupby([a.index, 'id']).cumcount()
b['helper'] = b.groupby([b.index, 'id']).cumcount()
a = a.rename_axis('date')
b = b.rename_axis('date')

a.merge(b, on=['date','id','helper']).drop('helper', axis=1)

Output:

           id    w         x
date                        
2020-01-31  A  0.5  0.947632
2020-02-28  B  0.5  0.226547
2020-01-31  A  0.5  0.594420
2020-02-28  B  0.5  0.428309

這似乎不是合並問題,而是更多地滿足了我。 添加似乎工作

a['x'] = b['x']

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM