如何找到重叠的intervalIndex pandas

lf5gs5x2  于 11个月前  发布在  其他
关注(0)|答案(4)|浏览(90)

我有一个包含索引下限和上限的框架,具有相应的值,我试图匹配相应索引的值。我的框架由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的value加到df2上,只要索引在lowhigh之间,结果如下:

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]


但是这需要很多时间,而且每次我的记忆都失败了。有没有什么快速的方法可以找到重叠的时间间隔?

px9o7tmv

px9o7tmv1#

这里有一个解决方案 * 假设索引是排序的 *,创建一个dict与limit的,并使用dict对框架,然后使用ffill()来填补Map创建的空白。

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()

个字符

cetgtptt

cetgtptt2#

使用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

xkrw2x1b

xkrw2x1b3#

这个帖子已经有一段时间没有被打开了。但是我最近遇到了一个类似的问题。我发现这个问题已经用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

xtfmy6hx

xtfmy6hx4#

conditional_join是一个扩展性很好的有效选项,它可以有效地处理不等式连接:

# pip install pyjanitor
import janitor

(df2
.conditional_join(
    df1, 
    ('index', 'low', '>='), 
    ('index', 'high', '<='), 
    df_columns='index', 
    right_columns='value')
)
   index  value
0      4     10
1      5     10
2      6     10
3      7     15
4      8     20
5      9     20

字符串

相关问题