繁体   English   中英

在包含范围的熊猫df中搜索

[英]searching in a pandas df that contains ranges

我有一个熊猫df,其中包含2列“开始”和“结束”(均为整数)。 我想要一种有效的方法来搜索行,以便由行[start,end]表示的范围包含特定值。

另外两个注意事项:

  1. 可以假设范围不重叠
  2. 该解决方案应支持批处理模式-给定输入列表,输出将是包含匹配范围的行索引的映射(字典或其他方式)。

例如:

       start   end
0      7216    7342
1      7343    7343
2      7344    7471
3      7472    8239
4      8240    8495

和查询

[7215,7217,7344]

将导致

{7217: 0, 7344: 2}

谢谢!

蛮力解决方案,尽管可以使用很多改进。

df = pd.DataFrame({'start': [7216, 7343, 7344, 7472, 8240],
                   'end': [7342, 7343, 7471, 8239, 8495]})

search = [7215, 7217, 7344]
res = {}
for i in search:
    mask = (df.start <= i) & (df.end >= i)
    idx = df[mask].index.values
    if len(idx):
        res[i] = idx[0]
print res

产量

{7344: 2, 7217: 0}

选择的解决方案

此新解决方案可能具有更好的性能。 但是有一个限制,只有在范围之间没有间隙(如提供的示例)中一样,它才有效。

# Test data
df = pd.DataFrame({'start': [7216, 7343, 7344, 7472, 8240], 
                   'end': [7342, 7343, 7471, 8239, 8495]}, columns=['start','end'])

query = [7215,7217,7344]

# Reshaping the original DataFrame
df = df.reset_index()
df = pd.concat([df['start'], df['end']]).reset_index()
df = df.set_index(0).sort_index()
# Creating a DataFrame with a continuous index
max_range = max(df.index) + 1
min_range = min(df.index)
s = pd.DataFrame(index=range(min_range,max_range))
# Joining them
s = s.join(df)
# Filling the gaps
s = s.fillna(method='backfill')
# Then a simple selection gives the result
s.loc[query,:].dropna().to_dict()['index']

# Result
{7217: 0.0, 7344: 2.0}

先前的建议

# Test data
df = pd.DataFrame({'start': [7216, 7343, 7344, 7472, 8240], 
                   'end': [7342, 7343, 7471, 8239, 8495]}, columns=['start','end'])

# Constructing a DataFrame containing the query numbers
query = [7215,7217,7344]
result = pd.DataFrame(np.tile(query, (len(df), 1)), columns=query)

# Merging the data and the query
df = pd.concat([df, result], axis=1)

# Making the test
df = df.apply(lambda x: (x >= x['start']) & (x <= x['end']), axis=1).loc[:,query]
# Keeping only values found
df = df[df==True]
df = df.dropna(how='all', axis=(0,1))
# Extracting to the output format
result = df.to_dict('split')
result = dict(zip(result['columns'], result['index']))

# The result
{7217: 0, 7344: 2}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM