如何解决Pandas检查单行序列重复时的ValueError问题?
问题描述
我有一个包含9列的Pandas DataFrame(简称dataframe),其中5列名为['DEG1','DEG2','DEG3','DEG4','DEG5'],数据行数约2000行。我通过一个列表构建了另一个仅含1行、5列(对应上述DEG列)的小DataFrame(n_serie_df),需要检查该小DataFrame的整行序列是否在大DataFrame中重复存在。但运行代码时出现错误:ValueError: Item wrong length 1 instead of 1709,原代码如下:
import pandas as pd import numpy as np def check_repeated_deg(n_serie_list, dataframe): n_serie_dict = { "DEG1": [n_serie_list[0]], "DEG2": [n_serie_list[1]], "DEG3": [n_serie_list[2]], "DEG4": [n_serie_list[3]], "DEG5": [n_serie_list[4]], } n_serie_df = pd.DataFrame(n_serie_dict) repeated = dataframe[np.all(n_serie_df.values == n_serie_df.values, 1)].any().any() if repeated: return f"This deg serie is already measured" else: return None dataframe = pd.read_csv(r"data_deg.csv") n_serie_list = [2, 11, 21, 27, 41] result = check_repeated_deg(n_serie_list, dataframe) print(result)
错误原因
代码核心逻辑完全错误:判断条件里写的是n_serie_df.values == n_serie_df.values,相当于拿小DataFrame和自身比对,完全没用到目标大DataFrame。后续用这个仅1行长度的布尔数组去筛选1709行的大DataFrame时,必然触发长度不匹配的ValueError。
修正方案
以下两种方法均可实现需求,根据数据量和可读性选择:
方法一:NumPy广播逐行比对(高效适合大数据)
先从大DataFrame中提取目标5列,通过广播机制和小DataFrame的行做逐元素比对,再判断是否存在完全匹配的行:
import pandas as pd import numpy as np def check_repeated_deg(n_serie_list, dataframe): # 直接用列表构建小DataFrame,更简洁 n_serie_df = pd.DataFrame([n_serie_list], columns=['DEG1','DEG2','DEG3','DEG4','DEG5']) # 提取大DataFrame中的目标列 target_cols = dataframe[['DEG1','DEG2','DEG3','DEG4','DEG5']] # 逐行比对,检查是否存在完全匹配的行 repeated = np.any(np.all(target_cols.values == n_serie_df.values, axis=1)) return "This deg serie is already measured" if repeated else None dataframe = pd.read_csv(r"data_deg.csv") n_serie_list = [2, 11, 21, 27, 41] result = check_repeated_deg(n_serie_list, dataframe) print(result)
方法二:元组匹配(简洁易读)
将目标序列转为元组,再检查大DataFrame目标列组成的元组集合中是否包含该元组:
import pandas as pd def check_repeated_deg(n_serie_list, dataframe): target_tuple = tuple(n_serie_list) # 将大DataFrame的每行目标列转为元组,检查是否包含目标元组 repeated = target_tuple in dataframe[['DEG1','DEG2','DEG3','DEG4','DEG5']].apply(tuple, axis=1).values return "This deg serie is already measured" if repeated else None dataframe = pd.read_csv(r"data_deg.csv") n_serie_list = [2, 11, 21, 27, 41] result = check_repeated_deg(n_serie_list, dataframe) print(result)
内容的提问来源于stack exchange,提问作者lordUsuario
相关产品推荐
相关产品推荐

