Pandas 删除只有一种值的行,无论是否重复

2 投票
2 回答
64 浏览
提问于 2025-04-14 16:52

我想要删除那些所有值都相同的行,或者是相同值的组合。

比如,我有一个这样的数据表:

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

撰写回答