我需要帮助,以便根据条件和另一个数据框添加新列。我知道难度很高,但是我尝试添加自己能做的最大事例,并纠正一个简单的算法以完成我需要的工作。
这是我们将在其中添加列的主要数据框:
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中,我想添加2列,分别为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
所以让我们以一个例子来更好地理解:
df1
中的第一个Name
组 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.start1
( 830 )在以下时间间隔内:
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
如果有人有一些想法可以做到这一点,那就太好了。 非常感谢你
答案 0 :(得分:1)
从您的示例中还不清楚名称是否唯一,如果df1中的某个名称与df2中的多个名称匹配,该怎么办。
无论如何,我建议的过程是使用DataFrame.apply
方法。
Thats方法会收到一个函数,该函数将适用于每行(在args中指定axis = 1,否则默认为0),同时向每行添加新列(您的Newstart和Newend属性)。
示例:
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)
请注意,您必须返回已更改的行。
还请注意,返回值是一个新的DataFrame,不会破坏原始df1。
您可以阅读更多here