对于pandas数据帧中的一列,从当前行计算前第4、第8和第12行中列值的平均值



在pandas数据帧中,我想创建一个新列,用于计算当前行之前第4、第8和第12行的列值的平均值。

如下表所示,对于第13行:

第13行(第9行(之前4行的现有列中的值=4

第13行(第5行(之前8行的现有列中的值=6

第13行(第1行(之前12行的现有列中的值=2

4,6,2的平均值为4。因此,第13行的新列=4,对于1-12之间的其余行,新列=楠

我的df中有更多的行,但为了便于说明,我只添加了前13行。

新列
行号 现有列
1 2 NaN
2 4 NaN
3 3 NaN
4 1 NaN
5 6 NaN
6 4 NaN
7 8 NaN
8 2 NaN
9 4 NaN
10 9 NaN
11 2 NaN
12 4 NaN
13 3

.shift()是您缺少的部分。我们可以使用它来访问Pandas数据帧中现有行中的前几行。

让我们使用.groupby().apply().shift()如下:

df['New column'] = df.groupby((df['Row number'] - 1) // 13)['Existing column'].apply(lambda x: (x.shift(4) + x.shift(8) + x.shift(12)) / 3)

这里,通过将行分组在(df['Row number'] - 1) // 13设置的不同组号下,将行划分为13行的组

然后,在每个组中,我们在列Existing column上使用.apply(),并使用.shift()获得组中前面的第4、第8和第12个条目。

试运行

data = {'Row number' : np.arange(1, 40), 'Existing column': np.arange(11, 50) }
df = pd.DataFrame(data)
print(df)
Row number  Existing column
0            1               11
1            2               12
2            3               13
3            4               14
4            5               15
5            6               16
6            7               17
7            8               18
8            9               19
9           10               20
10          11               21
11          12               22
12          13               23
13          14               24
14          15               25
15          16               26
16          17               27
17          18               28
18          19               29
19          20               30
20          21               31
21          22               32
22          23               33
23          24               34
24          25               35
25          26               36
26          27               37
27          28               38
28          29               39
29          30               40
30          31               41
31          32               42
32          33               43
33          34               44
34          35               45
35          36               46
36          37               47
37          38               48
38          39               49
df['New column'] = df.groupby((df['Row number'] - 1) // 13)['Existing column'].apply(lambda x: (x.shift(4) + x.shift(8) + x.shift(12)) / 3)
print(df)
Row number  Existing column  New column
0            1               11         NaN
1            2               12         NaN
2            3               13         NaN
3            4               14         NaN
4            5               15         NaN
5            6               16         NaN
6            7               17         NaN
7            8               18         NaN
8            9               19         NaN
9           10               20         NaN
10          11               21         NaN
11          12               22         NaN
12          13               23        15.0
13          14               24         NaN
14          15               25         NaN
15          16               26         NaN
16          17               27         NaN
17          18               28         NaN
18          19               29         NaN
19          20               30         NaN
20          21               31         NaN
21          22               32         NaN
22          23               33         NaN
23          24               34         NaN
24          25               35         NaN
25          26               36        28.0
26          27               37         NaN
27          28               38         NaN
28          29               39         NaN
29          30               40         NaN
30          31               41         NaN
31          32               42         NaN
32          33               43         NaN
33          34               44         NaN
34          35               45         NaN
35          36               46         NaN
36          37               47         NaN
37          38               48         NaN
38          39               49        41.0
  1. 您可以将rolling.apply一起使用来应用自定义聚合函数
  2. (4,6,2(的平均值是4,而不是3
>>> (2 + 6 + 4) / 3
4.0
>>> df["New column"] = df["Existing column"].rolling(13).apply(lambda x: x.iloc[[0, 4, 8]].mean())
>>> df
Row number  Existing column  New column
0            1                2         NaN
1            2                4         NaN
2            3                3         NaN
3            4                1         NaN
4            5                6         NaN
5            6                4         NaN
6            7                8         NaN
7            8                2         NaN
8            9                4         NaN
9           10                9         NaN
10          11                2         NaN
11          12                4         NaN
12          13                3         4.0

分解:

  • CCD_ 11:选择";现有列";从数据帧
  • .rolling(13):从前13行开始,我们将在所有数据上移动一个滑动窗口。因此,首先,我们将遇到行0-12,然后是行1-13,然后是2-14,依此类推
  • .apply(...):对于前面提到的每个滚动部分,我们将应用一个对每个部分都有效的函数(在这种情况下,我们应用的函数是lambda
  • lambda x: x.iloc[[0, 4, 8]].mean():从每个轧制段中提取第0个、第4个和第8个(对应于第1行、第5行和第9行(,并计算并返回这些值的平均值

为了在块(或组(中而不是在滑动窗口中处理数据帧,您可以使用.groupby方法(而不是.rolling(应用相同的逻辑。

>>> groups = np.arange(len(df)) // 13 # defines groups as chunks of 13 rows
>>> averages = (
df.groupby(groups)["Existing column"]
.apply(lambda x: x.iloc[[0, 4, 8]].mean())
)
>>> averages.index = (averages.index + 1) * 13 - 1
>>> df["New column"] = averages
>>> df
Row number  Existing column  New column
0            1                2         NaN
1            2                4         NaN
2            3                3         NaN
3            4                1         NaN
4            5                6         NaN
5            6                4         NaN
6            7                8         NaN
7            8                2         NaN
8            9                4         NaN
9           10                9         NaN
10          11                2         NaN
11          12                4         NaN
12          13                3         4.0

现在分解:

  • groups = np.arange(len(df)):创建一个数组,该数组将用于将数据帧分块到组中。这个数组基本上是13个0,后面是13个1,然后是13个2。。。直到数组的长度与数据帧的长度相同。因此,在这种情况下,对于单个块示例,它将仅是一个1300的数组。

  • CCD_ 18根据上面定义的组对数据帧进行分组;现有列";

  • .apply(lambda x: x.iloc[[0, 4, 8]].mean()):概念上和以前一样,只是我们应用于每个分组而不是滑动窗口。

  • averages.index = (averages.index + 1) * 12:这个部分可能看起来有点奇怪。但我们本质上是在确保我们选择的平均值与原始数据集正确一致。在这种情况下,我们希望组0(在averages系列中用索引值0指定(的平均值与第12行对齐。如果我们有另一个组(组1,我们希望它与原始数据集中的第25行对齐(。所以我们可以用一点数学来做这个变换。

  • df["New column"] = averages:由于我们已经匹配了我们的指数,熊猫为我们负责这些新值的实际对齐。

相关内容

最新更新