我有一个数据框,其中包含索引的上下限,并带有相应的值,并且我正在尝试匹配te相应索引的值。我的数据框包含400.000行。我的数据框示例:
df1 = pd.DataFrame({'low':[4,7,8],'high':[6,7,21],'value':[10,15,20]})
df2 = pd.DataFrame({'index':[4,5,6,7,8,9]})
输出:
low high value
0 4 6 10
1 7 7 15
2 8 21 20
现在,只要索引在低和高之间,我想将df1的值添加到df2,结果如下:< / p>
index value
0 4 10
1 5 10
2 6 10
3 7 15
4 8 20
5 9 20
我尝试使用以下帖子制作intervalIndex:Searching a particular value in a range among two columns python dataframe
v = df1.loc[:, 'low':'high'].apply(tuple, 1).tolist()
idx = pd.IntervalIndex.from_tuples(v, 'both')
df2['value'] = df1.iloc[idx.get_indexer(df2['index'].values), 'value'].values
但是我的间隔保持重叠,我删除了重复的版本,但是我仍然需要删除一些重叠的间隔。找到它的一种方法是使用带有以下内容的for循环:
[idx.overlaps(x) for x in idx]
但是这会花费很多时间,并且每次我的内存出现故障时。有找到重叠间隔的快速方法吗?
答案 0 :(得分:1)
这是一个解决方案假设索引已排序,创建一个带有限制值的dict
,对数据框使用dict,然后使用ffill()
来填补地图创建的空白。 / p>
between_ = (
{**df1.set_index('low')['value'].to_dict(),
**df1.set_index('high')['value'].to_dict()}
)
# {4: 10, 7: 15, 8: 20, 6: 10, 21: 20}
df2['index'].map(between_).ffill()
0 10.0
1 10.0
2 10.0
3 15.0
4 20.0
5 20.0
Name: index, dtype: float64
答案 1 :(得分:1)
构建一个数据框以使用pd.concat()
df1 = pd.DataFrame({'low':[4,7,8],'high':[6,7,21],'value':[10,15,20]})
df2 = pd.DataFrame({'index':[4,5,6,7,8,9]}).set_index("index")
df2 = df2.join(pd.concat([pd.DataFrame(index=pd.RangeIndex(r[0],r[1]+1)).assign(value=r[2])
for r in df1.values])
)
输出
value
index
4 10
5 10
6 10
7 15
8 20
9 20
答案 2 :(得分:1)
打开此线程已有一段时间了。但是我最近也遇到了类似的问题。我发现使用Pandas IntervalIndex可以很好地解决该问题。
# Create an open IntervalIndex with both ends closed using setting 'both'
interval_idx = pd.IntervalIndex.from_arrays(df1.low, df1.high, 'both')
# Set the interval
df1 = df1.set_index(interval_idx)
# Define a function for getting all matching intervals from a dataframe
def get_interval_value(x, df=None):
if df is not None:
try:
res = df.loc[x].value
except:
res = None
else:
res = None
return res
# Compute interval overlaps
df2['value'] = df2['index'].apply(get_interval_value, df=df1)
返回df2
的期望结果:
index value
0 4 10
1 5 10
2 6 10
3 7 15
4 8 20
5 9 20