使用管道表达pandas子集

use*_*827 8 python pipe pandas

我有一个像我这样的子集的数据框:

   a  b   x  y
0  1  2   3 -1
1  2  4   6 -2
2  3  6   6 -3
3  4  8   3 -4

df = df[(df.a >= 2) & (df.b <= 8)]
df = df.groupby(df.x).mean()
Run Code Online (Sandbox Code Playgroud)

如何使用pandas管道运算符表达这一点?

df = (df
      .pipe((x.a > 2) & (x.b < 6)
      .groupby(df.x)
      .apply(lambda x: x.mean())
Run Code Online (Sandbox Code Playgroud)

Ami*_*ory 4

只要您可以将步骤分类为返回 DataFrame 并接受 DataFrame(可能带有更多参数)的步骤,那么您就可以使用pipe. 这样做是否有好处,是另一个问题。

例如,在这里您可以使用

df\
    .pipe(lambda df_, x, y: df_[(df_.a >= x) & (df_.b <= y)], 2, 8)\
    .pipe(lambda df_: df_.groupby(df_.x))\
    .mean()
Run Code Online (Sandbox Code Playgroud)

请注意,第一阶段是一个带有 3 个参数的 lambda,其中 2 和 8 作为参数传递。这不是唯一的方法 - 它相当于

    .pipe(lambda df_: df_[(df_.a >= 2) & (df_.b <= 8)])\
Run Code Online (Sandbox Code Playgroud)

另请注意,您可以使用

df\
    .pipe(lambda df_, x, y: df[(df.a >= x) & (df.b <= y)], 2, 8)\
    .groupby('x')\
    .mean()
Run Code Online (Sandbox Code Playgroud)

这里 lambda 接受df_,但对 进行操作df,第二个pipe已被替换为groupby

  • 第一个更改在这里有效,但很脆弱。它恰好可以工作,因为这是第一个管道阶段。例如,如果是后期阶段,它可能会采用一个维度的 DataFrame,并尝试在另一个维度的掩码上对其进行过滤。

  • 第二个改动就好了。从表面上看,我认为它更具可读性。基本上,任何接受 DataFrame 并返回 DataFrame 的东西都可以直接调用或通过pipe.