我有一个看起来像这样的Pandas数据框:
var1 var2
0 A_B_C_D 123
1 E_F_G_H 456
2 I_J_K_L 789
我想通过在'_'上拆分var1来查询数据帧,然后将其与我定义的另一个数组相匹配。假设数组是array_to_match_to =
['A', 'B', 'C', 'D']
,那么我想过滤数据帧以仅得到第0行。
另外,无论顺序如何,我都想匹配,因此匹配['D','A','B','C']也会返回第0行。
除了使用.iterrows
迭代df的所有行之外,还有一种简单而有效的方法吗?
答案 0 :(得分:0)
使用match = np.array(['A', 'B', 'C', 'D'])
df[(np.array(df.var1.str.split('_').values.tolist()) == match).all(1)]
var1 var2
0 A_B_C_D 123
np.core.defchararray.split
或match = np.array(['A', 'B', 'C', 'D'])
splits = np.stack(np.core.defchararray.split(df.var1.values.astype(str), '_'))
df[(splits == match).all(1)]
var1 var2
0 A_B_C_D 123
%timeit df[(np.array(df.var1.str.split('_').values.tolist()) == match).all(1)]
%timeit df[(np.stack(np.core.defchararray.split(df.var1.values.astype(str), '_')) == match).all(1)]
1000 loops, best of 3: 399 µs per loop
1000 loops, best of 3: 266 µs per loop
计时
"C:\\Users\\myuser"
答案 1 :(得分:0)
可以使用pd.Series.str
方法str.split
:
df['var1'] = df['var1'].str.split('_')
对于与顺序无关的匹配,事情比较棘手,如果只是尝试匹配一个外部列表,如示例所示,我可能首先通过在array_to_match_to上使用str.join
并查找匹配值来转移焦点,而不是在数据帧中分裂。
然后,为了将其扩展到array_to_match_to的所有排序,可以明确地采用排列,如下所示
from itertools import permutations
df[df['var1'].isin(['_'.join(m) for m in permutations(array_to_match_to)])]
array_to_match_to = ['A', 'B','C', 'D']
和array_to_match_to = ['D', 'A', 'B','C']
的第0行匹配哪些。
答案 2 :(得分:0)
您可以先拆分var1,对其进行排序,然后将其与匹配列表进行比较,得到一个掩码数组,然后用它来选择行。
df
Out[432]:
var1 var2
0 A_B_C_D 123
1 E_F_G_H 456
2 I_J_K_L 789
3 D_A_B_C 789
match= ['A', 'B', 'C', 'D']
df[df.var1.str.split('_').apply(sorted).apply(lambda x np.array_equal(x,match))]
Out[430]:
var1 var2
0 A_B_C_D 123
3 D_A_B_C 789