Python DataFrame删除连续重复行报错:ValueError问题求助
解决DataFrame删除door列连续重复行的问题及真值错误修复
首先,咱们先理清楚你遇到的ValueError的原因:你在if条件里直接使用了一个布尔类型的Series(也就是(mydf[['door']] != mydf[['door']].shift(-1)).any(axis=1)返回的结果),而pandas无法直接判断整个Series的"真值"——它不知道你是想判断任意一个元素为真还是所有元素为真,所以抛出了这个模糊性错误。
而且你的循环逻辑也有问题:你在循环里每次都检查整个DataFrame的条件,而不是针对当前行和前一行做对比。其实pandas有更高效的向量化操作来处理这种连续重复行的过滤,完全不需要用for循环。
正确的解决方案(向量化操作,推荐)
我们的目标是保留那些door列与前一行不同的行(第一行默认保留,因为没有前一行),具体代码如下:
import pandas as pd # 读取Excel数据 file_name = 'test.xlsx' df = pd.read_excel(file_name, header=0, index=False) # 按时间排序,确保顺序正确 mydf = df.sort_values(by='time') # 筛选出需要保留的行:当前行door与前一行不同,或第一行(shift()后第一行为NaN,用fillna(True)保留) filtered_df = mydf[mydf['door'] != mydf['door'].shift().fillna(True)] # 查看结果 print(filtered_df)
运行这段代码后,你会得到符合预期的结果:
time door name 0 00:01:10 in alex 2 02:01:10 out alex 3 03:01:10 in alex 4 04:01:10 out alex
为什么这个方法有效?
mydf['door'].shift()会把door列的所有元素向下移动一行,第一行变成NaNmydf['door'] != mydf['door'].shift()会生成一个布尔Series,标记哪些行的door值和前一行不同fillna(True)把第一行的NaN替换为True,确保第一行被保留- 最后用这个布尔Series来筛选DataFrame,就得到了去掉连续重复
door值的结果
如果你一定要用循环(不推荐,效率低)
如果只是想理解循环的正确写法,这里也提供一个示例:
import pandas as pd file_name = 'test.xlsx' df = pd.read_excel(file_name, header=0, index=False) mydf = df.sort_values(by='time') # 初始化一个列表标记需要保留的行,第一行默认保留 keep_rows = [True] # 从第二行开始遍历,对比当前行和前一行的door值 for i in range(1, len(mydf)): if mydf['door'].iloc[i] != mydf['door'].iloc[i-1]: keep_rows.append(True) else: keep_rows.append(False) # 筛选保留的行 filtered_df = mydf[keep_rows] print(filtered_df)
这个方法也能得到同样的结果,但对于大数据量来说,向量化操作的速度会快很多,所以更推荐第一种方法。
内容的提问来源于stack exchange,提问作者newbie
相关产品推荐
相关产品推荐

