我有一组包含多对值的大型(ish)实验数据。每对与特定条形码相关联。理想情况下,每对应具有唯一的条形码。不幸的是,事实证明我在实验过程中搞砸了一些东西。现在有几对共享一个条形码。我需要从我的分析中排除这些对/条形码。
我的数据看起来像这样:
对在列'A'和'B'中 - 我只是包含'X'来表示一些任意相关数据:
df = pd.DataFrame({'Barcode' : ['AABBCC', 'AABBCC', 'BABACC', 'AABBCC', 'DABBAC', 'ABDABD', 'DABBAC'],
'A' : ['v', 'v', 'x', 'y', 'z', 'h', 'z'],
'B' : ['h', 'h', 'j', 'k', 'l', 'v', 'l'],
'X' : np.random.randint(10, size = 7)})
df = df[['Barcode', 'A', 'B', 'X']]
df
Barcode A B X
0 AABBCC v h 8
1 AABBCC v h 7
2 BABACC x j 2
3 AABBCC y k 3
4 DABBAC z l 8
5 ABDABD h v 0
6 DABBAC z l 4
我想摆脱条形码'AABBCC'描述的行,因为这个条形码与两个不同的对相关联(行0和1都是同一对 - 这很好 - 但是,第3行是不同的对)。
df.loc[df.Barcode != 'AABBCC']
Barcode A B X
2 BABACC x j 6
4 DABBAC z l 0
5 ABDABD h v 7
6 DABBAC z l 5
到目前为止我的解决方案:
def duplicates(bar):
if len(df.loc[df.Barcode == bar].A.unique()) > 1 or len(df.loc[df.Barcode == bar].B.unique()) > 1:
return 'collision'
else:
return 'single'
df['Barcode_collision'] = df.apply(lambda row: duplicates(row['Barcode']), axis = 1)
df.loc[df.Barcode_collision == 'single']
Barcode A B X Barcode_collision
2 BABACC x j 6 single
4 DABBAC z l 0 single
5 ABDABD h v 7 single
6 DABBAC z l 5 single
不幸的是,使用我的精密计算机时,使用大型数据帧(约500,000行)非常慢。我敢肯定必须有更好/更快的方式。也许使用groupby函数?
df.groupby(['Barcode', 'A', 'B']).count()
X
Barcode A B
AABBCC v h 2
y k 1
ABDABD h v 1
BABACC x j 1
DABBAC z l 2
然后过滤掉第二个或第三个索引中具有多个值的行?但是我的大脑和谷歌搜索技巧似乎无法让我比这更进一步......
答案 0 :(得分:1)
您可以使用filter
:
print(df.groupby('Barcode').filter(lambda x: ((x.A.nunique() == 1) or (x.B.nunique() == 1))))
Barcode A B X Barcode_collision
2 BABACC x j 4 single
4 DABBAC z l 9 single
5 ABDABD h v 3 single
6 DABBAC z l 9 single
transform
和boolean indexing
的另一种解决方案:
g = df.groupby('Barcode')
A = g.A.transform('nunique')
B = g.B.transform('nunique')
print (df[(A == 1) | (B == 1)])
Barcode A B X Barcode_collision
2 BABACC x j 2 single
4 DABBAC z l 6 single
5 ABDABD h v 1 single
6 DABBAC z l 3 single