减少多列中的多个ID

时间:2018-04-24 12:20:00

标签: python pandas

我有一个DF的布局如下。实际的表格在+ 10m行的范围内,因此在较大的一侧。

df = pd.DataFrame({'id1' : ['12a', '13b', '14c', '15d', '16e', '18g', '17f', '19h']
                     ,'id2' : ['16e', '17f', '18g', '19h','12a', '14c','13b', '15d']
                     ,'var1' : [i for i in range(8)]
                     ,'var2' : list(np.random.randint(100, size = 8))
                     ,'var3' : [1, 2, np.nan, 3, 2, np.nan, np.nan, 34]
     })
>>> df
   id1  id2  var1  var2  var3
0  12a  16e     0    66   1.0
1  13b  17f     1     9   2.0
2  14c  18g     2    48   NaN
3  15d  19h     3    13   3.0
4  16e  12a     4    67   2.0
5  18g  14c     5    88   NaN
6  17f  13b     6    92   NaN
7  19h  15d     7    99  34.0

我想要的是减少DF中的ID,这些ID成对出现,例如 id1 索引行0,其中 id2 索引行4.所有ID都存在于两行中,我需要检查每一行并删除其中一行。目前我有一个解决方案,它是行迭代,有点慢。

请注意,由于需要检查所有ID( id1 vs id2 ),因此只能删除DF的下半部分(索引行4及以上)。

决赛桌将如下所示:

id1 id2  var1 var2
12a 16e  66   1.0
13b 17f  9    2.0
14c 18g  48   NaN
15d 19h  13   3.0

所有"快速"解决方案非常受欢迎。

1 个答案:

答案 0 :(得分:1)

我相信每行可以对列进行排序,只使用DataFrame.duplicatedboolean indexing过滤第一行,并按~反转掩码:

np.random.seed(2018)

df = pd.DataFrame({'id1' : ['12a', '13b', '14c', '15d', '16e', '18g', '17f', '19h']
                     ,'id2' : ['16e', '17f', '18g', '19h','12a', '14c','13b', '15d']
                     ,'var1' : [i for i in range(8)]
                     ,'var2' : list(np.random.randint(100, size = 8))
                     ,'var3' : [1, 2, np.nan, 3, 2, np.nan, np.nan, 34]
})

df = df[~pd.DataFrame(np.sort(df[['id1', 'id2']], 1)).duplicated()]
print (df)
   id1  id2  var1  var2  var3
0  12a  16e     0    62   1.0
1  13b  17f     1    59   2.0
2  14c  18g     2    58   NaN
3  15d  19h     3    72   3.0

<强>详情:

print (pd.DataFrame(np.sort(df[['id1', 'id2']], 1)))
     0    1
0  12a  16e
1  13b  17f
2  14c  18g
3  15d  19h
4  12a  16e
5  14c  18g
6  13b  17f
7  15d  19h

print (~pd.DataFrame(np.sort(df[['id1', 'id2']], 1)).duplicated())
0     True
1     True
2     True
3     True
4    False
5    False
6    False
7    False
dtype: bool