我有一个pandas系列 series
。如果我想要获得逐元素的floor或ceiling,是否有内置的方法或者我必须编写函数并使用apply?我问这个问题是因为数据很大,所以我非常重视效率。同时,这个问题还没有关于Pandas软件包的解答。
您可以使用NumPy的内置方法来完成此操作:np.ceil(series)
或np.floor(series)
。
两种方法都返回一个Series对象(而不是数组),因此会保留索引信息。
我是楼主,但我尝试了这个方法并且它起作用了:
np.floor(series)
更新:这个答案是错误的,请不要这样做。
说明:在大多数情况下,使用
Series.apply()
与本地矢量化NumPy函数是没有意义的,因为它将在Python循环中运行Numpy函数,导致性能大大降低。你最好直接使用np.floor(series)
,正如其他答案所建议的那样。
例如,您可以使用NumPy的floor来处理一个dataframe
:
floored_data = data.apply(np.floor)
我现在无法测试,但实际可行的解决方案可能不远了。
使用pd.Series.clip
,可以通过clip(lower=x)
或clip(upper=x)
设置最小值或最大值:
s = pd.Series([-1, 0, -5, 3])
print(s.clip(lower=0))
# 0 0
# 1 0
# 2 0
# 3 3
# dtype: int64
print(s.clip(upper=0))
# 0 -1
# 1 0
# 2 -5
# 3 0
# dtype: int64
pd.Series.clip
允许进行广义功能,例如同时应用和地板天花板限制,例如 s.clip(-1, 1)
注意: 此答案最初提到的是已在 pandas 1.0.0 中移除的 clip_lower
/ clip_upper
.
clip
等函数是有一定关联的,但是剪裁一个值与寻找该值的下限/上限是非常不同的操作... - Alex Rileys.clip(-1, np.inf)
或s.clip(-np.inf, 1)
来无缝处理这些情况。 - jpps = pd.Series([3.1, 2.2, 5.6])
,似乎没有办法仅使用clip
来计算与np.floor(s)
相同的结果。 (这并不是贬低你的答案,你的答案写得很好,提供了有用的信息 - 我只是在重新阅读问题时感到困惑。) - Alex Riley置顶答案已经是最快的了。这里我提供了一些使用纯pandas实现天花板和地板操作的替代方法,并将其与numpy方法进行了比较。
series = pd.Series(np.random.normal(100,20,1000000))
地板
%timeit np.floor(series) # 1.65 ms ± 18.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit series.astype(int) # 2.2 ms ± 131 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit (series-0.5).round(0) # 3.1 ms ± 47 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit round(series-0.5,0) # 2.83 ms ± 60.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit np.ceil(series) # 1.67 ms ± 21 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit (series+0.5).round(0) # 3.15 ms ± 46.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit round(series+0.5,0) # 2.99 ms ± 103 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Series
上使用round()
一样链接它? - iamyojimbopipe()
,df['column'].pipe(np.ceil)
。 - renan-eccel