首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何列出属于一组范围的所有数字对?

如何列出属于一组范围的所有数字对?
EN

Stack Overflow用户
提问于 2018-06-09 19:02:26
回答 4查看 389关注 0票数 6

假设我有dataframe df1,它包括两列-A和B。A的值代表下限范围,B的值代表上限范围。

代码语言:javascript
复制
  A     B
10.5  20.5
30.5  40.5
50.5  60.5

我有另一个数据帧,它包括两列-C&D,其中包含不同的数字范围。

代码语言:javascript
复制
  C     D
12.34  15.90
13.68  19.13
33.5   35.60
35.12  38.76
50.6   59.1

现在,我想列出df2中属于df1中的组(在下限和上限之间)的所有对。

最终输出应该是这样的-

代码语言:javascript
复制
     Key                Values
(10.5, 20.5)  [(12.34, 15.90), (13.68, 19.13)]
(30.5, 40.5)  [(33.5, 35.60), (35.12, 38.76)]
(50.5, 60.5)  [(50.6, 59.1)]

这个解决方案应该是有效的,因为我有5,000组范围和来自不同范围的85000个数字。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-06-09 19:43:56

它的速度不是很快(在我的电脑上大约30秒),但如果你有多个内核,使用multiprocessing包可以很容易地加速。

生成数据:

代码语言:javascript
复制
def get_fake(n):
    df = pd.DataFrame(np.random.rand(n * 2).reshape(-1, 2))
    df.loc[:, 1] += 1
    return df

df1 = get_fake(200)
df2 = get_fake(90000)

然后对于处理部分:

代码语言:javascript
复制
from collections import defaultdict
result = defaultdict(list)
for index, start, stop in df1.itertuples():
    subdf = df2[(start < df2.iloc[:, 0]) & (df2.iloc[:, 1] < stop)]
    result[(start, stop)] += subdf.values.tolist()

Result是一个字典,但如果需要,可以很容易地将其转换为Series。

票数 2
EN

Stack Overflow用户

发布于 2018-06-09 19:54:46

如果你使用interval index也就很容易了

代码语言:javascript
复制
idx = pd.IntervalIndex.from_arrays(df['A'],df['B'])
keys = df.values.tolist()
values = df2.groupby(df.loc[idx.get_indexer(df2['C'])].index).apply(lambda x : x.values)

new_df = pd.DataFrame({'key': keys , 'value': values})

          key                            value
0  [10.5, 20.5]  [[12.34, 15.9], [13.68, 19.13]]
1  [30.5, 40.5]   [[33.5, 35.6], [35.12, 38.76]]
2  [50.5, 60.5]                   [[50.6, 59.1]]

基于区间索引访问数据将为您提供关键字,以便您可以分组和聚合,即

代码语言:javascript
复制
df.loc[idx.get_indexer(df2['C'])]
     A     B
0  10.5  20.5
0  10.5  20.5
1  30.5  40.5
1  30.5  40.5
2  50.5  60.5
票数 2
EN

Stack Overflow用户

发布于 2018-06-09 22:57:03

一种解决方案是使用apply,例如:

代码语言:javascript
复制
# first create your output DF with the keys from your df with A and B
df = pd.DataFrame({'Key':[(a,b) for a,b in df1.itertuples(index=False)]})
# define a function to find the range in df2 within the range from the Keys column
def find_range( key, df_2):
    mask = (key[0] <= df_2['C']) & (key[1] >= df_2['D'])
    return [(c,d) for c,d in df_2[mask].itertuples(index=False)]
#now create the column Values with apply
df['Values'] = df['Key'].apply(find_range, args=(df2,))
# output
            Key                           Values
0  (10.5, 20.5)  [(12.34, 15.9), (13.68, 19.13)]
1  (30.5, 40.5)                   [(33.5, 35.6)]

注意:我假设在您的数据中,列C始终低于D,如果不是,您必须更改函数中的掩码,以检查C和D是否都在key和key1中。另外,我没有得到您所有的输入,所以第1行的值与您显示的值不同,但只是一个输入差异。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50773556

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档