是否可以在查询中使用切片?

Is it possible to use a slice in a query?

假设我有一个这样的数据框

import pandas as pd

df = pd.DataFrame({'A': list(range(5)), 'B': ['X_abc', 'Y_abc', 'abc', 'foo', 'Y_abc']})

我想在列B中查询某个值,我可以这样使用query

target = 'Y_abc'

df_ss = df.query('B == @target')

产生

   A      B
1  1  Y_abc
4  4  Y_abc

符合预期。

我现在想知道是否有使用切片的选项,例如像这样:

df_ss2 = df.query('B == @target[2:]')

这不起作用 returns

ValueError: "slice" is not a supported function

我当然可以用

df_ss3 = df.loc[df['B'] == target[2:]]

这给出了预期的输出

   A    B
2  2  abc

但我想知道我是否可以使用 query 实现同样的效果。可能吗?

您可以尝试以下技巧:

In [73]: df.query("B == @re.sub(r'^.{2}','', @target)")
Out[73]:
   A    B
2  2  abc

或者你可以写一个小的辅助函数:

In [90]: def my_slice(s, start=0, stop=None, step=None):
    ...:     return s[start:stop:step]
    ...:

In [91]: my_slice(target, 2)
Out[91]: 'abc'

In [92]: df.query("B == @my_slice(@target,2)")
Out[92]:
   A    B
2  2  abc

你可以这样做:

In [5]: s = slice(2, None)

In [6]: target[s]
Out[6]: 'abc'

In [7]: df.query('B == @target[@s]')
Out[7]: 
   A    B
2  2  abc

但真的,为什么不

df_ss2 = df.query('B == "%s"' % target[2:])

(或使用格式说明符或 f 字符串的变体)?将任何计算推入字符串以使其隐式计算而不是显式计算会有很多缺点,但除了语法糖之外我看不到很多优点。