如何在两个值之间的 DataFrame 中选择行

2024-12-24 08:56:00
admin
原创
120
摘要:问题描述:我正在尝试修改 DataFramedf以仅包含列中的值closing_price介于 99 和 101 之间的行,并尝试使用以下代码执行此操作。但是,我得到了错误ValueError:Series 的真值不明确。请使用 a.empty、a.bool()、a.item()、a.any() 或 a.al...

问题描述:

我正在尝试修改 DataFramedf以仅包含列中的值closing_price介于 99 和 101 之间的行,并尝试使用以下代码执行此操作。

但是,我得到了错误

ValueError:Series 的真值不明确。请使用 a.empty、a.bool()、a.item()、a.any() 或 a.all()

我想知道是否有一种不使用循环就能做到这一点的方法。

df = df[99 <= df['closing_price'] <= 101]

解决方案 1:

考虑Series.between:

df = df[df['closing_price'].between(99, 101)]

解决方案 2:

您应该使用()对布尔向量进行分组来消除歧义。

df = df[(df['closing_price'] >= 99) & (df['closing_price'] <= 101)]

解决方案 3:

有一个更好的选择 - 使用query()方法:

In [58]: df = pd.DataFrame({'closing_price': np.random.randint(95, 105, 10)})

In [59]: df
Out[59]:
   closing_price
0            104
1             99
2             98
3             95
4            103
5            101
6            101
7             99
8             95
9             96

In [60]: df.query('99 <= closing_price <= 101')
Out[60]:
   closing_price
1             99
5            101
6            101
7             99

更新:回答评论(编辑以修复小错误)

我喜欢这里的语法,但是在尝试与表达式结合时失败了:

df.query('(mean - 2*sd) <= closing_price <= (mean + 2*sd)')

我的数据都在平均值的 2 个标准差之内,因此我将执行 1 来演示:

In [161]: qry = ("(closing_price.mean() - closing_price.std())" +
     ...:        " <= closing_price <= " +
     ...:        "(closing_price.mean() + closing_price.std())")
     ...:

In [162]: df.query(qry)
Out[162]:
   closing_price
1             99
2             98
5            101
6            101
7             99
9             96

或者

In [163]: mean = df['closing_price'].mean()
     ...: sd = df['closing_price'].std()
     ...: df.query('(@mean - @sd) <= closing_price <= (@mean + @sd)')
     ...:
Out [163]:
   closing_price
1             99
2             98
5            101
6            101
7             99
9             96

解决方案 4:

newdf = df.query('closing_price.mean() <= closing_price <= closing_price.std()')

或者

mean = closing_price.mean()
std = closing_price.std()

newdf = df.query('@mean <= closing_price <= @std')

解决方案 5:

如果必须反复调用(针对不同的边界和),则许多工作会不必要地重复。在这种情况下,对帧/系列进行一次排序然后使用会很有帮助。我测得的速度提高了 25 倍,见下文。pd.Series.between(l,r) l`r`pd.Series.searchsorted()

def between_indices(x, lower, upper, inclusive=True):
    """
    Returns smallest and largest index i for which holds 
    lower <= x[i] <= upper, under the assumption that x is sorted.
    """
    i = x.searchsorted(lower, side="left" if inclusive else "right")
    j = x.searchsorted(upper, side="right" if inclusive else "left")
    return i, j

# Sort x once before repeated calls of between()
x = x.sort_values().reset_index(drop=True)
# x = x.sort_values(ignore_index=True) # for pandas>=1.0
ret1 = between_indices(x, lower=0.1, upper=0.9)
ret2 = between_indices(x, lower=0.2, upper=0.8)
ret3 = ...

基准

测量对 的重复评估(n_reps=100pd.Series.between()以及基于 的方法pd.Series.searchsorted(),针对不同的参数lowerupper。在我的 MacBook Pro 2015 上,使用 Python v3.8.0 和 Pandas v1.0.3,以下代码产生以下输出

# pd.Series.searchsorted()
# 5.87 ms ± 321 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
# pd.Series.between(lower, upper)
# 155 ms ± 6.08 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
# Logical expressions: (x>=lower) & (x<=upper)
# 153 ms ± 3.52 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
import numpy as np
import pandas as pd

def between_indices(x, lower, upper, inclusive=True):
    # Assumption: x is sorted.
    i = x.searchsorted(lower, side="left" if inclusive else "right")
    j = x.searchsorted(upper, side="right" if inclusive else "left")
    return i, j

def between_fast(x, lower, upper, inclusive=True):
    """
    Equivalent to pd.Series.between() under the assumption that x is sorted.
    """
    i, j = between_indices(x, lower, upper, inclusive)
    if True:
        return x.iloc[i:j]
    else:
        # Mask creation is slow.
        mask = np.zeros_like(x, dtype=bool)
        mask[i:j] = True
        mask = pd.Series(mask, index=x.index)
        return x[mask]

def between(x, lower, upper, inclusive=True):
    mask = x.between(lower, upper, inclusive=inclusive)
    return x[mask]

def between_expr(x, lower, upper, inclusive=True):
    if inclusive:
        mask = (x>=lower) & (x<=upper)
    else:
        mask = (x>lower) & (x<upper)
    return x[mask]

def benchmark(func, x, lowers, uppers):
    for l,u in zip(lowers, uppers):
        func(x,lower=l,upper=u)

n_samples = 1000
n_reps = 100
x = pd.Series(np.random.randn(n_samples))
# Sort the Series.
# For pandas>=1.0:
# x = x.sort_values(ignore_index=True)
x = x.sort_values().reset_index(drop=True)

# Assert equivalence of different methods.
assert(between_fast(x, 0, 1, True ).equals(between(x, 0, 1, True)))
assert(between_expr(x, 0, 1, True ).equals(between(x, 0, 1, True)))
assert(between_fast(x, 0, 1, False).equals(between(x, 0, 1, False)))
assert(between_expr(x, 0, 1, False).equals(between(x, 0, 1, False)))

# Benchmark repeated evaluations of between().
uppers = np.linspace(0, 3, n_reps)
lowers = -uppers
%timeit benchmark(between_fast, x, lowers, uppers)
%timeit benchmark(between, x, lowers, uppers)
%timeit benchmark(between_expr, x, lowers, uppers)

解决方案 6:

相反

df = df[99 <= df['closing_price'] <= 101]

你应该用这个

df = df[(99 <= df['closing_price']) & (df['closing_price'] <= 101)]

我们必须使用 NumPy 的按位逻辑运算符|, &, ~,^来进行复合查询。此外,括号对于运算符优先级也很重要。

欲了解更多信息,请访问链接:比较、掩码和布尔逻辑(摘自 Jake VanderPlas 撰写的《Python 数据科学手册》)。

解决方案 7:

如果您要处理多个值和多个输入,也可以设置这样的应用函数。在这种情况下,过滤数据框中属于特定范围内的 GPS 位置。

def filter_values(lat,lon):
    if abs(lat - 33.77) < .01 and abs(lon - -118.16) < .01:
        return True
    elif abs(lat - 37.79) < .01 and abs(lon - -122.39) < .01:
        return True
    else:
        return False


df = df[df.apply(lambda x: filter_values(x['lat'],x['lon']),axis=1)]
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用