.query在 apandas.DataFrame和括号运算符中使用方法有什么区别?对我来说,它们似乎做同样的事情,只是语法不同。我错过了什么吗?为什么我会选择一种方式而不是另一种方式?
我想说两者几乎相同,但 query() 的出现与括号运算符相比几乎没有什么好处。
根据数据的大小、所需的性能和维护代码的难易程度,总会有一些权衡。
根据熊猫文档:
您可以获得框架的值,其中 b 列的值介于 a 列和 c 列的值之间。例如:
df = DataFrame({
'a': np.random.choice(10, 5),
'b': np.random.choice(10, 5),
'c': np.random.choice(10, 5),
})
pure python
df[(df['a'] < df['b']) & (df['b'] < df['c'])]
query
df.query('(a<b) & (b<c)')
Run Code Online (Sandbox Code Playgroud)
对于大帧,使用 numexpr 的 DataFrame.query() 比 Python 稍快。
注意:只有当您的框架超过大约 200,000 行时,您才会看到将 numexpr 引擎与 DataFrame.query() 一起使用的性能优势。
query()和bracket语法比较
Full numpy-like syntax:
df = pd.DataFrame(np.random.randint(n, size=(n, 3)), columns=list('abc'))
df.query('(a < b) & (b < c)')
df[(df['a'] < df['b']) & (df['b'] < df['c'])]
Slightly nicer by removing the parentheses (by binding making comparison operators bind tighter than & and |).
df.query('a < b & b < c')
Use English instead of symbols:
df.query('a < b and b < c')
Pretty close to how you might write it on paper:
df.query('a < b < c')
Run Code Online (Sandbox Code Playgroud)
query() 的一个用例是当您有一组 DataFrame 对象时,这些对象具有共同的列名(或索引级别/名称)的子集。您可以将相同的查询传递给两个框架,而无需指定您对查询感兴趣的框架
df1 = DataFrame({
'a':np.random.choice(10, 5),
'b':np.random.choice(10, 5),
'c':np.random.choice(10, 5),
})
df2 = DataFrame({
'a':np.random.choice(np.arange(5,15,3), 8),
'b':np.random.choice(np.arange(5,13,2), 8),
'c':np.random.choice(np.arange(3,11,3), 8),
})
expr = '4<a<c<9'
map(lambda frame:frame.query(expr), [df1, df2])
Run Code Online (Sandbox Code Playgroud)
in与not in运营商query() 还支持 Python 的 in 和 not in 比较运算符的特殊使用,为调用 Series 或 DataFrame 的 isin 方法提供简洁的语法。
get all rows where columns "a" and "b" have overlapping values
df = pd.DataFrame({'y': list('aabbccddeeff'), 'z': list('aaaabbbbcccc'),
'c': np.random.randint(5, size=12),
'd': np.random.randint(9, size=12)})
df.query('y in z')
How you'd do it in pure Python
df[df['y'].isin(df['z'])]
df.query('y not in z')
pure Python
df[~df['y'].isin(df['z'])]
Run Code Online (Sandbox Code Playgroud)
您可以将其与其他表达式结合起来进行非常简洁的查询:
rows where cols a and b have overlapping values and col c's values are less than col d's
df.query('y in z and c > d')
pure python
df[(df.y.isin(df.z)) & (df.c > df.d)]
Run Code Online (Sandbox Code Playgroud)
注意:请注意 in 和 not in 在 Python 中进行计算,因为 numexpr 没有与此操作等效的操作。然而,只有 in/not in 表达式本身在 vanilla Python 中被评估。
For example, in the expression
df.query('a in b + c + d')
(b + c + d) is evaluated by numexpr and then the in operation is evaluated in plain Python. In general, any
operations that can be evaluated using numexpr will be.
Run Code Online (Sandbox Code Playgroud)
==运算符与列表对象的特殊使用Comparing a list of values to a column using ==/!= works similarly to in/not in.
df.query('z == ["y", "z", "c"]')
it is equivalent to - df.query('z in ["y", "z", "c"]')
which one is faster in or ==?
both are almost same
df.query('z == ["y", "z", "c"]')
pure python
df[df['z'].isin(['y','z','c'])]
df.query('c == [1, 2]')
df.query('c != [1, 2]')
df.query('[1, 2] in c')
df.query('[1, 2] not in c')
pure Python
df[df['c'].isin([1, 2])]
Run Code Online (Sandbox Code Playgroud)
You can negate boolean expressions with the word not or the ~ operator.
df = pd.DataFrame(np.random.rand(n, 3), columns=list('abc'))
df['bools'] = np.random.rand(len(df)) > 0.5
df.query('~bools')
df.query('not bools')
df.query('not bools') == df[~df['bools']]
Of course, expressions can be arbitrarily complex too:
short query syntax
shorter = df.query('a < b < c and (not bools) or bools > 2')
equivalent in pure Python
longer = df[(df['a'] < df['b']) & (df['b'] < df['c']) & (~df['bools']) | (df['bools'] > 2)]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
76 次 |
| 最近记录: |