pandas 基于落在范围内的位置将一个 Dataframe Map到另一个 Dataframe

flvlnr44  于 2023-08-01  发布在  其他
关注(0)|答案(1)|浏览(83)

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

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

字符串
我有另一个dataframe 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


我希望我的最终数据框架基本上通过找到位于其中一个区域内的位置来Mapdf1到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'])]

yyyllmsg

yyyllmsg1#

我假设每个唯一的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


注意:我做了一些粗略的基准测试,在600 k/1.2M长度的 Dataframe 上做这个工作只花了不到2分钟(5700 x/Python 3.10)

相关问题