按标准从 pandas 数据框(或 numpy ndarray?)中选择

2024-04-12

我发现自己正在编写这种模式a lot:

tmp = <some operation>
result = tmp[<boolean expression>]
del tmp

...在哪里<boolean expression>被理解为一个布尔表达式涉及 tmp。 (暂且,tmp始终是 pandas 数据框,但我认为如果我使用 numpy ndarrays,会出现相同的模式 - 不确定。)

例如:

tmp = df.xs('A')['II'] - df.xs('B')['II']
result = tmp[tmp < 0]
del tmp

正如人们可以从del tmp最后,only创建原因tmp根本就是这样我可以在应用于它的索引表达式中使用涉及它的布尔表达式。

I would love to eliminate the need for this (otherwise useless) intermediate, but I don't know of any efficient1 way to do this. (Please, correct me if I'm wrong!)

作为第二好,我想将这种模式推到一些辅助函数中。问题是找到一个合适的方法来通过<boolean expression>到它。我只能想到不雅的。例如。:

def filterobj(obj, criterion):
    return obj[eval(criterion % 'obj')]

This actually works2:

filterobj(df.xs('A')['II'] - df.xs('B')['II'], '%s < 0')

# Int
# 0     -1.650107
# 2     -0.718555
# 3     -1.725498
# 4     -0.306617
# Name: II

...但是使用eval总是让我感觉很恶心……如果还有其他方法,请告诉我。


1E.g., any approach I can think of involving the filter built-in is probably ineffiencient, since it would apply the criterion (some lambda function) by iterating, "in Python", over the panda (or numpy) object...

2The definition of df used in the last expression above would be something like this:

import itertools
import pandas as pd
import numpy as np
a = ('A', 'B')
i = range(5)
ix = pd.MultiIndex.from_tuples(list(itertools.product(a, i)),
                               names=('Alpha', 'Int'))
c = ('I', 'II', 'III')
df = pd.DataFrame(np.random.randn(len(idx), len(c)), index=ix, columns=c)

由于 Python 的工作方式,我认为这会很困难。我只能想到一些技巧,这些技巧只能让你达到目标的一部分。就像是

def filterobj(obj, fn):
    return obj[fn(obj)]

filterobj(df.xs('A')['II'] - df.xs('B')['II'], lambda x: x < 0)

应该可以,除非我错过了一些东西。以这种方式使用 lambda 是延迟求值的常用技巧之一。

大声思考:一个人可以做一个this未评估但仅作为表达式保留的对象,例如

>>> this
this
>>> this < 3
this < 3
>>> df[this < 3]
Traceback (most recent call last):
  File "<ipython-input-34-d5f1e0baecf9>", line 1, in <module>
    df[this < 3]
[...]
KeyError: u'no item named this < 3'

然后特殊情况的处理this进入 pandas 或仍然具有类似的功能

def filterobj(obj, criterion):
    return obj[eval(str(criterion.subs({"this": "obj"})))]

(如果工作足够多,我们可能会失去eval,这只是概念证明)之后类似

>>> tmp = df["I"] + df["II"]
>>> tmp[tmp < 0]
Alpha  Int
A      4     -0.464487
B      3     -1.352535
       4     -1.678836
Dtype: float64
>>> filterobj(df["I"] + df["II"], this < 0)
Alpha  Int
A      4     -0.464487
B      3     -1.352535
       4     -1.678836
Dtype: float64

会工作。我不确定这些是否值得让人头疼,不过,Python 不太适合这种风格。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

按标准从 pandas 数据框(或 numpy ndarray?)中选择 的相关文章

随机推荐