如何在一个数据框中标记或 select 行,其中值位于另一个具有附加标识符的数据框中的任何范围之间
How to mark or select rows in one dataframe, where value lies between any of the ranges in another dataframe featuring additional identifier
我是一个该死的初学者,正在使用 pandas 和 numpy 来处理科学数据帧。
我有 2 个大型数据框,一个带有坐标(geneX - 位置),另一个带有坐标范围(基因 - 开始 - 结束)。我想select(或标记)第一个数据集中的所有行,坐标是否落在第二个数据框中的任何范围内。
例如:
import pandas as pd
import numpy as np
test = {'A': ['gene1','gene1','gene2','gene3','gene3','gene3','gene4'],
'B': [1,11,21,31,41,51,61],
'C': [10,20,30,40,50,60,70],
'D': [4,64,25,7,36,56,7]}
df1 = pd.DataFrame(test, columns = ['A', 'D'])
df2 = pd.DataFrame(test, columns = ['A', 'B', 'C'])
这给出了两个如下所示的数据框:
df1:
A D
0 gene1 4 <-- I want this row
1 gene1 64
2 gene2 25 <-- and this row
3 gene3 7
4 gene3 36 <-- and this row
5 gene3 56 <-- and this row
6 gene4 7
df2:
A B C
0 gene1 1 10
1 gene1 11 20
2 gene2 21 30
3 gene3 31 40
4 gene3 41 50
5 gene3 51 60
6 gene4 61 70
我成功走到了这一步:
for i,j in zip(df2["B"],df2["C"]):
x=df1[(df1["D"] >=i ) & (df1["D"] <= j)]
df_final.append(x)
df_final=pd.concat(df_final,axis=0).reset_index(drop=True)
df_final=df_final.drop_duplicates()
df_final
但这只检查 df1'D' 中的值是否在 df2 中的任何范围内,但我未能合并“基因”标识符。基本上,我需要 df1 中的每一行循环遍历 df2 并首先检查基因是否匹配,如果匹配,则检查坐标是否在数据范围内。
谁能帮我解决这个问题?
附加问题:我可以做到吗,所以它会保留 df1 intakt,只在直接匹配条件的行后面创建一个带有“true”的新列?如果不是,我会从 selected 行创建一个新的 df,添加一个带有“true”标签的列,然后将其合并回第一个。
感谢您的帮助。非常感谢!
让我们分步进行
- 重置
df1
的索引
- 在
A
列上将 df1
与 df2
合并(基本上合并具有相同基因的行)
- 查询合并的数据框以过滤列
D
介于 B
和 C
之间的行
- 通过测试过滤行
index
列中df1
的index
的成员资格来标记行
m = df1.reset_index().merge(df2, on='A').query('B <= D <= C')
df1['flag'] = df1.index.isin(m['index'])
print(df1)
A D flag
0 gene1 4 True
1 gene1 64 False
2 gene2 25 True
3 gene3 7 False
4 gene3 36 True
5 gene3 56 True
6 gene4 7 False
我是一个该死的初学者,正在使用 pandas 和 numpy 来处理科学数据帧。
我有 2 个大型数据框,一个带有坐标(geneX - 位置),另一个带有坐标范围(基因 - 开始 - 结束)。我想select(或标记)第一个数据集中的所有行,坐标是否落在第二个数据框中的任何范围内。
例如:
import pandas as pd
import numpy as np
test = {'A': ['gene1','gene1','gene2','gene3','gene3','gene3','gene4'],
'B': [1,11,21,31,41,51,61],
'C': [10,20,30,40,50,60,70],
'D': [4,64,25,7,36,56,7]}
df1 = pd.DataFrame(test, columns = ['A', 'D'])
df2 = pd.DataFrame(test, columns = ['A', 'B', 'C'])
这给出了两个如下所示的数据框:
df1:
A D
0 gene1 4 <-- I want this row
1 gene1 64
2 gene2 25 <-- and this row
3 gene3 7
4 gene3 36 <-- and this row
5 gene3 56 <-- and this row
6 gene4 7
df2:
A B C
0 gene1 1 10
1 gene1 11 20
2 gene2 21 30
3 gene3 31 40
4 gene3 41 50
5 gene3 51 60
6 gene4 61 70
我成功走到了这一步:
for i,j in zip(df2["B"],df2["C"]):
x=df1[(df1["D"] >=i ) & (df1["D"] <= j)]
df_final.append(x)
df_final=pd.concat(df_final,axis=0).reset_index(drop=True)
df_final=df_final.drop_duplicates()
df_final
但这只检查 df1'D' 中的值是否在 df2 中的任何范围内,但我未能合并“基因”标识符。基本上,我需要 df1 中的每一行循环遍历 df2 并首先检查基因是否匹配,如果匹配,则检查坐标是否在数据范围内。
谁能帮我解决这个问题?
附加问题:我可以做到吗,所以它会保留 df1 intakt,只在直接匹配条件的行后面创建一个带有“true”的新列?如果不是,我会从 selected 行创建一个新的 df,添加一个带有“true”标签的列,然后将其合并回第一个。
感谢您的帮助。非常感谢!
让我们分步进行
- 重置
df1
的索引
- 在
A
列上将df1
与df2
合并(基本上合并具有相同基因的行) - 查询合并的数据框以过滤列
D
介于B
和C
之间的行
- 通过测试过滤行
index
列中df1
的index
的成员资格来标记行
m = df1.reset_index().merge(df2, on='A').query('B <= D <= C')
df1['flag'] = df1.index.isin(m['index'])
print(df1)
A D flag
0 gene1 4 True
1 gene1 64 False
2 gene2 25 True
3 gene3 7 False
4 gene3 36 True
5 gene3 56 True
6 gene4 7 False