我只想从数据框中删除特定子集中的重复项。我想在“ A”列中的每个“ spec”下删除重复项,但我想在整个数据帧中保留重复项(可以在第一个“ spec”下包含一些行,这些行与第二个“规范”,但在“规范”下,直到下一个“规范”,我要删除重复项)
这是数据框
df
A B C
spec first second
test text1 text2
act text12 text13
act text14 text15
test text32 text33
act text34 text35
test text85 text86
act text87 text88
test text1 text2
act text12 text13
act text14 text15
test text85 text86
act text87 text88
spec third fourth
test text1 text2
act text12 text13
act text14 text15
test text85 text86
act text87 text88
test text1 text2
act text12 text13
act text14 text15
test text85 text86
act text87 text88
这就是我想要的:
df
A B C
spec first second
test text1 text2
act text12 text13
act text14 text15
test text32 text33
act text34 text35
test text85 text86
act text87 text88
spec third fourth
test text1 text2
act text12 text13
act text14 text15
test text85 text86
act text87 text88
我可以将数据帧拆分为“少量”数据帧,然后为每个“少量”数据帧进行for循环丢弃重复,最后将它们连接起来,但是我想知道是否还有其他解决方案。
我也尝试过并成功:
dfList = df.index[df["A"] == "spec"].tolist()
dfList = np.asarray(dfList)
for dfL in dfList:
idx = np.where(dfList == dfL)
if idx[0][0]!=(len(dfList)-1):
df.loc[dfList[idx[0][0]]:dfList[idx[0][0]+1]-1]
= df.loc[dfList[idx[0][0]]:dfList[idx[0][0]+1]-1].drop_duplicates()
else:
df.loc[dfList[idx[0][0]]:] = df.loc[dfList[idx[0][0]]:].drop_duplicates()
编辑: 我必须将此添加到末尾:
df.dropna(how ='all',inplace = True)
但是我只是想知道是否还有其他解决方案。
答案 0 :(得分:1)
使用groupby
+ duplicated
:
df[~df.groupby(df.A.eq('spec').cumsum()).apply(lambda x: x.duplicated()).values]
A B C
0 spec first second
1 test text1 text2
2 act text12 text13
3 act text14 text15
4 test text32 text33
5 act text34 text35
6 test text85 text86
7 act text87 text88
13 spec third fourth
14 test text1 text2
15 act text12 text13
16 act text14 text15
17 test text85 text86
18 act text87 text88
详细信息
我们使用cumsum
查找特定“ spec”条目下的所有行。组标签为:
df.A.eq('spec').cumsum()
0 1
1 1
2 1
3 1
4 1
5 1
6 1
7 1
8 1
9 1
10 1
11 1
12 1
13 2
14 2
15 2
16 2
17 2
18 2
19 2
20 2
21 2
22 2
23 2
Name: A, dtype: int64
然后对该系列进行分组,并计算每个组的重复项:
df.groupby(df.A.eq('spec').cumsum()).apply(lambda x: x.duplicated()).values
array([False, False, False, False, False, False, False, False, True,
True, True, True, True, False, False, False, False, False,
False, True, True, True, True, True])
由此,剩下的就是保留与“ False”相对应的那些行(即,未重复)。
答案 1 :(得分:0)
这应该有效:
df2 = df.drop_duplicates(subset=['A', 'B','C'])
答案 2 :(得分:0)
另一种可能的解决方案可能是... 您可以拥有一个计数器,并使用计数器值从A列创建一个新列,只要您在该列值中遇到规范,就可以增加计数器值。
counter = 0
def counter_fun(val):
if val == 'spec': counter+=1
return counter
df['new_col'] = df.A.apply(counter_fun)
然后在new_col上进行分组,并删除重复项。