我有两个带有日期时间索引的数据框。
import pandas as pd
d = {'dat': ['2016-01-01', '2016-01-02', '2016-01-03', '2017-01-01', '2017-01-02', '2017-01-03'],'x': [1, 2, 3, 4, 5, 6]}
df1 = pd.DataFrame(d)
df1.set_index(['dat'], inplace=True)
df1.index = pd.to_datetime(df1.index)
d = {'dat': ['2016-01-01', '2017-01-01'],'y': [10, 11]}
df2 = pd.DataFrame(d)
df2.set_index(['dat'], inplace=True)
df2.index = pd.to_datetime(df2.index)
DF1:
x
dat
2016-01-01 1
2016-01-02 2
2016-01-03 3
2017-01-01 4
2017-01-02 5
2017-01-03 6
df2:
y
dat
2016-01-01 10
2017-01-01 11
我想只使用索引的年份和月份加入他们。 所以输出结果如下:
DF3:
x y
dat
2016-01-01 1 10
2016-01-02 2 10
2016-01-03 3 10
2017-01-01 4 11
2017-01-02 5 11
2017-01-03 6 11
我尝试使用
加入他们df1.join(df2, how='inner')
我知道我可以像这样提取年份和月份:
df1.index.map(lambda x: x.strftime('%Y-%m'))
df2.index.map(lambda x: x.strftime('%Y-%m'))
但我想知道如何将所有这些结合起来以达到预期效果?
非常感谢
答案 0 :(得分:4)
您要合并的信息不会在任何地方明确定义。当我们合并而不破坏它时,将日期保留在索引中并不是一件好事。因此,我们将索引移动到适当的数据框并创建两个要合并的新列。即,year
和month
。我将这部分包含在一个函数中,以便更好地了解其中发生的事情。
def f(df):
df = df.reset_index()
return df.assign(year=df.dat.dt.year, month=df.dat.dt.month)
df = f(df1).merge(f(df2), on=['year', 'month'], suffixes=['', '_'])
df.set_index('dat')[['x', 'y']]
x y
dat
2016-01-01 1 10
2016-01-02 2 10
2016-01-03 3 10
2017-01-01 4 11
2017-01-02 5 11
2017-01-03 6 11
这是使用pd.Index.map
和to_period
的不同概念。创建从df2
映射的字典映射,将年/月期对象转换为列y
中的对应值。然后使用map
将df1.index
中的定期日期映射到正确的y
值。
m = dict(zip(df2.index.to_period('M'), df2.y))
df1.assign(y=df1.index.to_period('M').map(m.get))
x y
dat
2016-01-01 1 10
2016-01-02 2 10
2016-01-03 3 10
2017-01-01 4 11
2017-01-02 5 11
2017-01-03 6 11
设置
dates1 = ['2016-01-01', '2016-01-02', '2016-01-03',
'2017-01-01', '2017-01-02', '2017-01-03']
df1 = pd.DataFrame({'x': range(1, 7)}, pd.DatetimeIndex(dates1, name='dat'))
dates2 = ['2016-01-01', '2017-01-01']
df2 = pd.DataFrame({'y': [10, 11]}, pd.DatetimeIndex(dates2, name='dat'))
答案 1 :(得分:3)
您可以使用merge
与assign
year
和month
来自DateTimeIndex:
df3 = (df1.assign(year=df1.index.year, month=df1.index.month)
.merge(df2.assign(year=df2.index.year, month=df2.index.month), on =['year','month'],right_index=True)
.drop(['year','month'],axis=1))
输出:
x y
dat
2016-01-01 1 10
2016-01-02 2 10
2016-01-03 3 10
2017-01-01 4 11
2017-01-02 5 11
2017-01-03 6 11