根据另一个数据框的范围从数据框中选择最小值
Selecting minimum from dataframe based on range from another dataframe
我有一个数据 df1
作为:
Type StDt EnDt
A 1/2/2012 1/4/2012
B 1/6/2012 1/6/2012
我有另一个数据框 df2
,所有日期到 2019 年为:
KBWI
Date
2012-01-02 45.00
2012-01-03 32.00
2012-01-04 14.00
2012-01-05 26.00
2012-01-06 27.00
对于 df1
中的每一行,我需要使用日期范围 StDt、EnDt 从 df2 中提取所有行并取其最小值以获得以下内容:
Type StDt EnDt Minimum
A 1/2/2012 1/4/2012 14.00
B 1/6/2012 1/6/2012 27.00
由于数据帧很大,我不确定如何有效地做到这一点。
初步准备:将所有涉及的列和索引转换为 datetime
。
df[['StDt', 'EnDt']] = df[['StDt', 'EnDt']].apply(pd.to_datetime, errors='coerce')
df2.index = pd.to_datetime(df2.index, errors='coerce')
df
Type StDt EnDt
0 A 2012-01-02 2012-01-04
1 B 2012-01-06 2012-01-06
df2
KBWI
Date
2012-01-02 45.0
2012-01-03 32.0
2012-01-04 14.0
2012-01-05 26.0
2012-01-06 27.0
一个简单的方法是使用pd.IntervalIndex
和groupby
找到最小值:
idx = pd.IntervalIndex.from_arrays(df['StDt'], df['EnDt'], closed='both')
df['Minimum'] = df2['KBWI'].groupby(idx.get_indexer_non_unique(df2.index)).min()
df
Type StDt EnDt Minimum
0 A 2012-01-02 2012-01-04 14.0
1 B 2012-01-06 2012-01-06 27.0
假设 df
的索引也是 RangeIndex
(数字,单调递增)。
一个老问题; pd.merge_asof
应该在这里很好地工作,特别是因为其中一个数据框只有两行(最终目标是最小值):
(pd.merge_asof(df2, df1, left_index=True, right_on='StDt')
.query('Date <= EnDt')
.groupby('Type')
.min()
)
Out[204]:
KBWI StDt EnDt
Type
A 14.0 2012-01-02 2012-01-04
B 27.0 2012-01-06 2012-01-06
我有一个数据 df1
作为:
Type StDt EnDt
A 1/2/2012 1/4/2012
B 1/6/2012 1/6/2012
我有另一个数据框 df2
,所有日期到 2019 年为:
KBWI
Date
2012-01-02 45.00
2012-01-03 32.00
2012-01-04 14.00
2012-01-05 26.00
2012-01-06 27.00
对于 df1
中的每一行,我需要使用日期范围 StDt、EnDt 从 df2 中提取所有行并取其最小值以获得以下内容:
Type StDt EnDt Minimum
A 1/2/2012 1/4/2012 14.00
B 1/6/2012 1/6/2012 27.00
由于数据帧很大,我不确定如何有效地做到这一点。
初步准备:将所有涉及的列和索引转换为 datetime
。
df[['StDt', 'EnDt']] = df[['StDt', 'EnDt']].apply(pd.to_datetime, errors='coerce')
df2.index = pd.to_datetime(df2.index, errors='coerce')
df
Type StDt EnDt
0 A 2012-01-02 2012-01-04
1 B 2012-01-06 2012-01-06
df2
KBWI
Date
2012-01-02 45.0
2012-01-03 32.0
2012-01-04 14.0
2012-01-05 26.0
2012-01-06 27.0
一个简单的方法是使用pd.IntervalIndex
和groupby
找到最小值:
idx = pd.IntervalIndex.from_arrays(df['StDt'], df['EnDt'], closed='both')
df['Minimum'] = df2['KBWI'].groupby(idx.get_indexer_non_unique(df2.index)).min()
df
Type StDt EnDt Minimum
0 A 2012-01-02 2012-01-04 14.0
1 B 2012-01-06 2012-01-06 27.0
假设 df
的索引也是 RangeIndex
(数字,单调递增)。
一个老问题; pd.merge_asof
应该在这里很好地工作,特别是因为其中一个数据框只有两行(最终目标是最小值):
(pd.merge_asof(df2, df1, left_index=True, right_on='StDt')
.query('Date <= EnDt')
.groupby('Type')
.min()
)
Out[204]:
KBWI StDt EnDt
Type
A 14.0 2012-01-02 2012-01-04
B 27.0 2012-01-06 2012-01-06