Pandas 删除只有一种值的行,无论是否重复
我想要删除那些所有值都相同的行,或者是相同值的组合。
比如,我有一个这样的数据表:
data = {'A': ['1, 1, 1', '1', '2', '3', '1'],
'B': ['1', '1,1,1,1', '2', '4', '1'],
'C': ['1, 1', '2', '3', '5', '1']}
我想要删除那些所有列的值都是'1',或者是任何组合的'1'的行。最终的结果应该像这样:
data = {'A': ['1', '2', '3'],
'B': ['1,1,1,1', '2', '4'],
'C': ['2', '3', '5']}
我试过以下方法:
def remove_rows_with_ones(value):
return all(x == '1' for x in value.split(','))
mask = df.apply(lambda row: any(remove_rows_with_ones(val) for val in row), axis=1)
df_filtered = df[~mask]
但是似乎没有效果。
2 个回答
0
下面的代码可以正常运行。如果all_same
里的item
被设置为None,那么它会删除所有单元格只有一个值的行;如果不是None,它只会删除所有单元格都是“1”的行。
import pandas as pd
data = {'A': ['1, 1, 1', '1', '2', '3', '1'],
'B': ['1', '1,1,1,1', '2', '4', '1'],
'C': ['1, 1', '2', '3', '5', '1']}
df = pd.DataFrame(data)
def all_same(row, item='1'):
cc = set()
for val in row:
try:
val = set(val.replace(" ", "").split(","))
except AttributeError: # cell with non-string value!
# decide if you want to ignore this, or reraise this
# for simplicity I just `pass`
pass
cc.update(val)
if item is not None:
return cc == {item}
return len(cc) == 1
df = df[~df.apply(all_same, axis=1)]
2
你可以把数据转换成字符串,然后检查每个单元格里是否有除了 1
以外的其他字符(比如空格或逗号)。如果至少有一个单元格满足这个条件,就保留这一行:
out = df[df.apply(lambda s: s.astype(str).str.contains('[^1 ,]')).any(axis=1)]
或者,按照你最初的想法,用 ', '
来分割字符串:
import re
out = df[~df.applymap(lambda c: all(x=='1' for x in re.split(', *', c))).all(axis=1)]
# pandas ≥ 2.1
out = df[~df.map(lambda c: all(x=='1' for x in re.split(', *', c))).all(axis=1)]
输出结果:
A B C
1 1 1,1,1,1 2
2 2 2 3
3 3 4 5
中间结果:
# df.apply(lambda s: s.astype(str).str.contains('[^1 ,]'))
A B C
0 False False False
1 False False True
2 True True True
3 True True True
4 False False False
# df.map(lambda c: all(x=='1' for x in re.split(', *', c)))
A B C
0 True True True
1 True True False
2 False False False
3 False False False
4 True True True