mor*_*rty 8 python duplicates dataframe pandas
请考虑以下数据帧
import pandas as pd
df = pd.DataFrame({'A' : [1, 2, 3, 3, 4, 4, 5, 6, 7],
'B' : ['a','b','c','c','d','d','e','f','g'],
'Col_1' :[np.NaN, 'A','A', np.NaN, 'B', np.NaN, 'B', np.NaN, np.NaN],
'Col_2' :[2,2,3,3,3,3,4,4,5]})
df
Out[92]:
A B Col_1 Col_2
0 1 a NaN 2
1 2 b A 2
2 3 c A 3
3 3 c NaN 3
4 4 d B 3
5 4 d NaN 3
6 5 e B 4
7 6 f NaN 4
8 7 g NaN 5
Run Code Online (Sandbox Code Playgroud)
我想删除与列有关的所有重复行'A' 'B'.我想删除有条目的NaN条目(我知道所有的dulicates都会有一个NaN和一个非NaN条目).最终结果应如下所示
A B Col_1 Col_2
0 1 a NaN 2
1 2 b A 2
2 3 c A 3
4 4 d B 3
6 5 e B 4
7 6 f NaN 4
8 7 g NaN 5
Run Code Online (Sandbox Code Playgroud)
所有高效的单行都是最受欢迎的
如果目标是仅删除NaN重复项,则需要稍微更复杂的解决方案.
首先,排序on A,B和Col_1,因此NaNs被移动到每个组的底部.然后调用df.drop_duplicates具有keep=first:
out = df.sort_values(['A', 'B', 'Col_1']).drop_duplicates(['A', 'B'], keep='first')
print(out)
A B Col_1 Col_2
0 1 a NaN 2
1 2 b A 2
2 3 c A 3
4 4 d B 3
6 5 e B 4
7 6 f NaN 4
8 7 g NaN 5
Run Code Online (Sandbox Code Playgroud)
这是一个替代方案:
df[~((df[['A', 'B']].duplicated(keep=False)) & (df.isnull().any(axis=1)))]
# A B Col_1 Col_2
# 0 1 a NaN 2
# 1 2 b A 2
# 2 3 c A 3
# 4 4 d B 3
# 6 5 e B 4
# 7 6 f NaN 4
# 8 7 g NaN 5
Run Code Online (Sandbox Code Playgroud)
这使用按位“非”运算符~来消除满足作为重复行的联合条件的行(该参数keep=False使该方法对所有非唯一行的结果都为True),并且至少包含一个null值。因此,表达式在哪里df[['A', 'B']].duplicated(keep=False)返回此Series:
# 0 False
# 1 False
# 2 True
# 3 True
# 4 True
# 5 True
# 6 False
# 7 False
# 8 False
Run Code Online (Sandbox Code Playgroud)
...表达式df.isnull().any(axis=1)返回该Series:
# 0 True
# 1 False
# 2 False
# 3 True
# 4 False
# 5 True
# 6 False
# 7 True
# 8 True
Run Code Online (Sandbox Code Playgroud)
...我们将它们都包装在括号中(在索引操作中使用多个表达式时,Pandas语法都需要),然后再次将它们包装在括号中,这样我们就可以否定整个表达式(~( ... )例如),如下所示:
~((df[['A','B']].duplicated(keep=False)) & (df.isnull().any(axis=1))) & (df['Col_2'] != 5)
# 0 True
# 1 True
# 2 True
# 3 False
# 4 True
# 5 False
# 6 True
# 7 True
# 8 False
Run Code Online (Sandbox Code Playgroud)
您可以通过进一步使用逻辑运算符&和|(或“或”运算符)来建立更复杂的条件。与SQL一样,根据需要用附加括号将条件分组。例如,使用基于逻辑“ 条件X和条件Y都为真,或条件Z为真”的过滤器df[ ( (X) & (Y) ) | (Z) ]。