根据pandas中的另一个dafaframe添加两个新列

2024-04-28 07:41:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要帮助,以便根据条件和另一个数据帧添加新列。我知道难度很大,但我尽量添加了最多的示例,并修改了一个简单的算法,以满足我的需要

以下是我们将添加列的主要数据框:

df1

Name        start1 end1 strand length 
OK0100087.1 187    250  +      63
OK0100087.1 830    750  -      80
OK0100087.1 500    625  +      125
OK0100087.1 375    275  -      100   
OK0100087.1 150    20   -      120
OK0100088.1 600    1000  +     400

从这个df中,我想添加两列,分别为Newstart和``Newend'``` df2

Name        start1 end1 strand length Newstart Newend 
OK0100087.1 187    250  +      63
OK0100087.1 830    750  -      80
OK0100087.1 500    625  +      125
OK0100087.1 375    275  -      100   
OK0100087.1 150    20   -      120
OK0100088.1 600    1000 +      400

为了填充空单元格,我们将使用另一个df,例如:

df2

Name        start_plus end_plus start_minus end_minus 
OK0100087.1_0 0          375      1000        625
OK0100087.1_1 376        750      624         250 
OK0100087.1_3 751        1000     249         0 
OK0100088.1   0          12000    0           12000
OK0100089.1_0 0          566      3000        2433
OK0100089.1_1 567        3000     2432        0

想法是让每一行检查串值,然后执行如下算法:

if df1.strand.eq("-"):
   df1.Newstart = df1.start1 - df2.end_minus
   df1.Newend = df1.Newstart - df1.length

if df1.strand.eq("+"):
   df1.Newstart = df1.start1 - df2.start_plus
   df1.Newend = df1.Newstart + df1.length

因此,让我们举个例子来更好地理解:

第一Name组在df1中OK0100087.1

Name        start1 end1 strand length Newstart Newend 
OK0100087.1 187    250  +      63
OK0100087.1 830    750  -      80
OK0100087.1 500    625  +      125
OK0100087.1 375    275  -      100   
OK0100087.1 150    20   -      120

第一行是+链,然后是df1.end1=250

在df2中,我们只将df2.Names.str.contains(df1.Name)250保持在

Name          start_plus end_plus 
OK0100087.1_0 0          375

(我将start_plus和end_plus作为间隔,因为它是+串)

所以

if df1.strand.eq("+"):
   df1.Newstart = df1.start1 - df2.start_plus
   (df1.Newstart = 187 - 0 = 187
   df1.Newend = df1.Newstart + df1.length
   (df1.Newend =187+63 = 250)

其中:

Name        start1 end1 strand length Newstart Newend 
OK0100087.1 187    250  +      63     187      250
OK0100087.1 830    750  -      80
OK0100087.1 500    625  +      125
OK0100087.1 375    275  -      100   
OK0100087.1 150    20   -      120
OK0100088.1 500    700  +      200

现在,让我们为第二行执行此操作:

strand.eq("-"),因此df1.start1830)在以下时间间隔内:

Name          start_minus end_minus 
OK0100087.1_0 1000        625

所以

if df1.strand.eq("-"):
   df1.Newstart = df1.start1 - df2.end_minus
   (df1.Newstart = 830 - 625 =205)
   df1.Newend = df1.Newstart - df1.length
   df1.Newend = 205 - 80 = 125) 

其中:

Name        start1 end1 strand length Newstart Newend 
OK0100087.1 187    250  +      63     187      250
OK0100087.1 830    750  -      80     205      125
OK0100087.1 500    625  +      125
OK0100087.1 375    275  -      100   
OK0100087.1 150    20   -      120
OK0100088.1 500    700  +      200

等等

Name        start1 end1 strand length Newstart Newend 
OK0100087.1 187    250  +      63     187      250
OK0100087.1 830    750  -      80     205      125
OK0100087.1 500    625  +      125    125      250
OK0100087.1 375    275  -      100    125      25
OK0100087.1 150    20   -      120    150      20
OK0100088.1 600    1000 +      200    33       433

如果有人有一些想法,为了做到这一点,这将是惊人的。 多谢各位


Tags: nameifplusstartlengthendeqdf1
1条回答
网友
1楼 · 发布于 2024-04-28 07:41:41

从您的示例中不清楚名称是否唯一,以及如果来自df1的某些名称与来自df2的多个名称匹配,该怎么办

无论如何,我建议使用DataFrame.apply方法。 该方法在向每一行(Newstart和Newend属性)添加新列时接收一个它将应用于每一行的函数(在args中指定axis=1,否则默认为0)

例如:

def func(row-from-df):
    df2Portion = d2[d2[Name].str.contains(row-from-df[Name], na=False)]  # using vectorize string

    if row-from-df.strand.eq('+'):
        # your logic here, you can add rows etc..
    else:
        # your logic here

    return row-from-df

df1.apply(func, axis=1)

请注意,必须返回已更改的行

还请注意,返回值是一个新的数据帧,而不是更改原始df1

你可以阅读更多here

相关问题 更多 >