小能豆

更多 Pythonic/Pandaic 方法来循环遍历 pandas 系列

py

这很可能是非常基本的东西,但我搞不懂。假设我有这样的系列:

s1 = pd.Series([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4])

如何才能对该系列的子系列进行操作而不必恢复使用 for 循环?

例如,假设我想将其转换为一个包含四个元素的新系列。这个新系列中的第一个元素是原始系列中前三个元素的总和 (1, 1, 1),第二个元素是后三个元素的总和 (2, 2, 2),依此类推:

s2 = pd.Series([3, 6, 9, 12])

我怎样才能做到这一点?


阅读 6

收藏
2024-11-13

共1个答案

小能豆

您可以使用groupby聚合函数来实现这一点,或者使用rolling窗口以更高效和矢量化的方式对子系列执行操作,而无需诉诸for循环。

对于您想要对每 3 个元素求和的特定示例,您可以执行以下操作:

使用groupby和的解决方案transform

您可以按自定义键对值进行分组,例如,将索引除以 3(每 3 个连续元素分组)。分组后,您可以将函数应用于sum每个组:

import pandas as pd

# Create the original Series
s1 = pd.Series([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4])

# Group by every 3 consecutive elements and apply sum
s2 = s1.groupby(s1.index // 3).sum()

print(s2)

输出:

0     3
1     6
2     9
3    12
dtype: int64

解释:

  • s1.index // 3:通过将索引除以 3 来创建组,结果为[0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3]。因此,每 3 个连续元素都会落入同一组中。
  • .groupby(...):这根据结果索引对系列进行分组。
  • .sum():最后,我们对每个组内的值求和。

解决方案使用rolling(如果您正在考虑移动窗口方法):

另一个选择是使用rolling系列创建一个窗口并应用聚合函数,例如sum

s2 = s1.rolling(3).sum().dropna()

print(s2)

输出:

2     3.0
3     6.0
4     9.0
5    12.0
dtype: float64

解释:

  • .rolling(3):这将创建一个大小为 3 的滚动窗口。
  • .sum():将求和函数应用于滚动窗口。
  • .dropna()``NaN:由于前两个元素没有足够的数据来形成完整窗口,因此删除滚动窗口产生的初始值。

为什么要选择其中一个而不是另一个?

  • groupby当您需要按某些条件分组或对分组数据执行更复杂的操作时,方法通常更灵活。
  • rolling方法通常用于滑动窗口上的操作,但如果需要固定大小的窗口(如 3 个连续元素的总和),该方法也会很好用

这两种方法都很高效,避免了显式循环,并且利用了 pandas 的内部优化。

2024-11-13