4

我有两个数据框,df1并且df2.

df1:

contig  position   tumor_f  t_ref_count  t_alt_count
1     14599  0.000000            1            0
1     14653  0.400000            3            2
1     14907  0.333333            6            3
1     14930  0.363636            7            4 

df2:

contig  position
1     14599
1     14653

我想从 df1 中删除具有匹配 contig 的行,df2 中的位置值。类似于:df1[df1[['contig','position']].isin(df2[['contig','position']])] 除非这不起作用。

4

3 回答 3

3

您可以对 Series 执行此操作isin两次(适用于 0.12):

In [21]: df1['contig'].isin(df2['contig']) & df1['position'].isin(df2['position'])
Out[21]:
0     True
1     True
2    False
3    False
dtype: bool

In [22]: ~(df1['contig'].isin(df2['contig']) & df1['position'].isin(df2['position']))
Out[22]:
0    False
1    False
2     True
3     True
dtype: bool

In [23]: df1[~(df1['contig'].isin(df2['contig']) & df1['position'].isin(df2['position']))]
Out[23]:
   contig  position   tumor_f  t_ref_count  t_alt_count
2       1     14907  0.333333            6            3
3       1     14930  0.363636            7            4

isin也许我们可以在 0.13 中得到一个简洁的解决方案(在 Tom 的回答中使用 DataFrame )。

感觉应该有一种巧妙的方法来使用内部合并来做到这一点......

In [31]: pd.merge(df1, df2, how="inner")
Out[31]:
   contig  position  tumor_f  t_ref_count  t_alt_count
0       1     14599      0.0            1            0
1       1     14653      0.4            3            2
于 2013-07-31T20:45:17.613 回答
3

.13 版正在向 DataFrame 添加一个isin方法来实现这一点。如果您使用的是当前的主人,您可以尝试:

In [46]: df1[['contig', 'position']].isin(df2.to_dict(outtype='list'))
Out[46]: 
  contig position
0   True     True
1   True     True
2   True    False
3   True    False

要获取未包含的元素,请使用~not 和 index

In [45]: df1.ix[~df1[['contig', 'position']].isin(df2.to_dict(outtype='list')).
all(axis=1)]
Out[45]: 
   contig  position   tumor_f  t_ref_count  t_alt_count
2       1     14907  0.333333            6            3
3       1     14930  0.363636            7            4
于 2013-07-31T19:50:28.463 回答
1

这是一个详细的方法:

iter1 = df1[['contig', 'position']].itertuples()
is_in_other_df = []
for row in iter1:
    tup2 = df2.itertuples()
    is_in_other_df.append(row in tup2)
df1["InOtherDF"] = is_in_other_df

然后只需删除“InOtherDF”所在的行True。在返回行元组时,您可能需要稍微调整它以忽略索引。

我认为这是一种更清洁的使用方式merge

df2["FromDF2"] = True
df1 = pandas.merge(df1, df2, left_on=["contig", "position"], 
                   right_on=["contig", "position"], how="left")
df1[~df1.FromDF2]
于 2013-07-31T19:42:31.940 回答