根据范围内的位置将一个数据帧映射到另一个数据帧

问题描述 投票:0回答:1

我有一个数据框(600k 行)

index  chr     position    other_cols
1      1          100      ...
2      1          2100    
3      1          3300
4      2          4
5      2          2200
6      3          8420

我有另一个数据框 df2(120 万行):

index          chr       start       stop
    1          1         1           100
    2          1         2000        3000 
    3          1         4000        8000 
    4          2         1           1500
    5          3         20          40000 

我希望我的最终数据框通过查找位于某个区域内的位置来基本上将 df1 映射到 df2。 :

index  chr     position    matched_start  matched_end  other_cols (from df1)
1      1          100          1           100            ...
2      1          2100         2000        3000  
3      2          4            1           1500
4      3          8420         20          40000 

这是我尝试运行的代码,但每次我尝试在整个 dfs 上运行时,我的笔记本电脑都会崩溃(仅当我使用小子集时才有效)。我也尝试过分块进行,但它也导致我的笔记本电脑崩溃。

# Merge the DataFrames based on the 'chromosome' column
merged_df = pd.merge(df1, df2, on='chr', how='inner')


# Filter the rows where variant_position lies within the start/end ranges
filtered_df = merged_df[(merged_df['position'] >= merged_df['start']) & (merged_df['position'] <= merged_df['end'])]

python pandas dataframe dataset mapping
1个回答
0
投票

我假设每个唯一的

chr
没有任何重叠的间隔(并假设
df2
按起始位置排序):

x = df2.groupby('chr')[['start', 'stop']].agg(list)

all_dfs = []
for ch, g in df1.groupby('chr'):
    start_arr, stop_arr = np.array(x.loc[ch, 'start']), np.array(x.loc[ch, 'stop'])
    idx = np.searchsorted(start_arr, g['position']) - 1
    g.loc[:, ['matched_start', 'matched_end']] = np.array([start_arr[idx], stop_arr[idx]]).T
    all_dfs.append(g[g['position'] <= stop_arr[idx]])

df = pd.concat(all_dfs)
print(df)

打印:

   index  chr  position  other_col  matched_start  matched_end
0      1    1       100          1              1          100
1      2    1      2100          2           2000         3000
3      4    2         4          4              1         1500
5      6    3      8420          6             20        40000

初始

df1

   index  chr  position  other_col
0      1    1       100          1
1      2    1      2100          2
2      3    1      8300          3
3      4    2         4          4
4      5    2      2200          5
5      6    3      8420          6

初始

df2

   index  chr  start   stop
0      1    1      1    100
1      2    1   2000   3000
2      3    1   4000   8000
3      4    2      1   1500
4      5    3     20  40000

注意:我做了一些粗略的基准测试,在 600k/1.2M 长度的数据帧上执行此操作花了我不到 2 分钟的时间 (5700x/Python 3.10)

© www.soinside.com 2019 - 2024. All rights reserved.