如果日期介于另一个数据框中的两个日期之间,创建新列并分配值的最佳方法是什么?
e.g。
dataframe A
date values
2017-05-16 x
2017-04-12 Y
dataframe B #df contains dates to use to filter and associated id
start end id
2017-05-08 2017-05-18 34
2017-04-24 2017-05-08 33
2017-04-03 2017-04-24 32
期望的结果
dataframe A
date values id
2017-05-16 x 34
2017-04-12 Y 32
我已经查看了pd.cut,它似乎对我想要的东西不起作用,并且编写一个循环来迭代多个条件的数据帧似乎效率低下。
答案 0 :(得分:4)
使用IntervalIndex
,这是Pandas 0.20.0中的新功能。这看起来仍处于试验阶段,因此其他解决方案可能更可靠。
# Get the 'id' column indexed by the 'start'/'end' intervals.
s = pd.Series(df_b['id'].values, pd.IntervalIndex.from_arrays(df_b['start'], df_b['end']))
# Map based on the date of df_a.
df_a['id'] = df_a['date'].map(s)
结果输出:
date values id
0 2017-05-16 x 34
1 2017-04-12 Y 32
或者,如果您不介意更改df_b
的索引,您可以直接转换为IntervalIndex
:
# Create an IntervalIndex on df_b.
df_b = df_b.set_index(['start', 'end'])
df_b.index = pd.IntervalIndex.from_tuples(df_b.index)
# Map based on the date of df_a.
df_a['id'] = df_a['date'].map(df_b['id'])
答案 1 :(得分:2)
这是一个在sql的一个步骤中非常简单的事情的例子,但在Pandas中却没有那么多。因此,条件是我不喜欢这种方法,这就是它。
_
# First Full Outer Join Dataframes
# (Requires a Common Column in Pandas Unlike SQL)
df_A['fake key'] = 1
df_B['fake key'] = 1
outer_join = pd.merge(df_A, df_B, how='outer', on='fake key')
# Now Filter Back down to Desired Rows/Columns
desired_rows = outer_join.query('date < end and date > start')
desired_columns = ['date', 'values', 'id']
final = desired_rows[desired_columns]
final
输出:
date values id
0 2017-05-16 x 34
5 2017-04-12 y 32
让这个答案有些不满意的事情是: