假设我有dataframe df1,它包括两列-A和B。A的值代表下限范围,B的值代表上限范围。
A B
10.5 20.5
30.5 40.5
50.5 60.5
我有另一个数据帧,它包括两列-C&D,其中包含不同的数字范围。
C D
12.34 15.90
13.68 19.13
33.5 35.60
35.12 38.76
50.6 59.1
现在,我想列出df2中属于df1中的组(在下限和上限之间)的所有对。
最终输出应该是这样的-
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个数字。
发布于 2018-06-09 19:43:56
它的速度不是很快(在我的电脑上大约30秒),但如果你有多个内核,使用multiprocessing
包可以很容易地加速。
生成数据:
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)
然后对于处理部分:
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。
发布于 2018-06-09 19:54:46
如果你使用interval index
也就很容易了
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]]
基于区间索引访问数据将为您提供关键字,以便您可以分组和聚合,即
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
发布于 2018-06-09 22:57:03
一种解决方案是使用apply
,例如:
# 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行的值与您显示的值不同,但只是一个输入差异。
https://stackoverflow.com/questions/50773556
复制相似问题