我有一个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
所有"快速"解决方案非常受欢迎。
答案 0 :(得分:1)
我相信每行可以对列进行排序,只使用DataFrame.duplicated
按boolean 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