这是问题所在:我知道如何在索引或列上合并两个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))
所需的输出:
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
请注意,我正在寻找一种通用的解决方案,其中a
和b
不一定包含id
中的相同索引或元素。
答案 0 :(得分:2)
IIUC,您可以使用set_index
附加列,使用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
答案 1 :(得分:1)
您可以简单地使用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”列,我不太确定)。请让我知道两个数据框的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)
输出:
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
答案 2 :(得分:1)
使用基于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)
输出:
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
答案 3 :(得分:0)
这似乎不是合并问题,但更多的是养活我。 添加似乎可行
a['x'] = b['x']