如何筛选含numpy数组列的Pandas DataFrame及获取唯一行?
问题描述
我有一个包含数组列的Pandas DataFrame,想要基于该数组列的值筛选DataFrame。示例DataFrame如下:
subject position current_choice inpt 837 ash [0.0, 0.005792712956593603, 0.0207826510381976... -1.0 [-0.0625, 1.0, 1.0] 838 zad [0.0, -0.00044640180445325853, -0.000892803608... 1.0 [1.0, -1.0, -1.0] 839 pop [0.0, 5.2698260765019904e-05, 0.00010539652153... 1.0 [0.0625, 1.0, 1.0] 840 syc [0.0, 0.0031267642423531117, 0.014658282457501... 1.0 [1.0, 1.0, 1.0] 841 ash [0.0, -0.00013353844781401902, -0.000267076895... -1.0 [-0.125, 1.0, 1.0]
尝试执行df[df['inpt']==[0.0625, 1.0, 1.0]]时,出现如下错误:
ValueError: ('Lengths must match to compare', (95994,), (3,))
请问该如何解决这个筛选问题?另外,如何查找该数组列中的唯一行?
解决方案
一、解决数组列筛选报错问题
直接用==对比数组列和目标数组会报错,原因是Pandas会尝试按元素维度匹配对比,但列的长度和目标数组长度不匹配。可以用以下两种可行方法:
方法1:逐行对比数组
通过apply遍历inpt列的每个数组元素,和目标数组做相等判断:
target = [0.0625, 1.0, 1.0] filtered_df = df[df['inpt'].apply(lambda x: x == target)]
如果数组里是浮点数,要注意精度误差,建议用numpy.allclose做近似对比:
import numpy as np filtered_df = df[df['inpt'].apply(lambda x: np.allclose(x, target))]
方法2:拆分数组列为多列后筛选
把inpt列的数组拆分成单独的列,再按普通列的逻辑筛选:
# 将inpt列拆分为三列 inpt_cols = pd.DataFrame(df['inpt'].tolist(), index=df.index, columns=['inpt_0', 'inpt_1', 'inpt_2']) # 直接基于拆分后的列筛选原DataFrame filtered_df = df[(inpt_cols['inpt_0'] == 0.0625) & (inpt_cols['inpt_1'] == 1.0) & (inpt_cols['inpt_2'] == 1.0)]
二、查找数组列的唯一行
因为列表(数组)不可哈希,无法直接用drop_duplicates,可以通过以下方法处理:
方法1:转元组后去重
把数组转为可哈希的元组,再用drop_duplicates去重:
# 新增元组列作为去重依据 df['inpt_tuple'] = df['inpt'].apply(tuple) # 按元组列去重后删除辅助列 unique_df = df.drop_duplicates(subset=['inpt_tuple']).drop(columns=['inpt_tuple'])
方法2:用numpy视图转换去重
利用numpy数组的视图生成可哈希标识,实现去重:
import numpy as np # 把数组转为numpy的uint8视图作为唯一标识 df['inpt_hash'] = df['inpt'].apply(lambda x: np.asarray(x).view(np.uint8)) # 去重后删除辅助列 unique_df = df.drop_duplicates(subset=['inpt_hash']).drop(columns=['inpt_hash'])
方法3:基于集合去重(仅适用于不关心元素顺序的场景)
如果只在意数组内的元素集合是否唯一,不关心顺序,可以用frozenset:
df['inpt_set'] = df['inpt'].apply(frozenset) unique_df = df.drop_duplicates(subset=['inpt_set']).drop(columns=['inpt_set'])
内容的提问来源于stack exchange,提问作者Jaweria Amjad
相关产品推荐
相关产品推荐

