繁体   English   中英

Pandas DataFrame 过滤多列上的行组

[英]Pandas DataFrame filtering of groups of rows on multiple columns

这是我的数据框的简化版本:

d = {'col1': ['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3', 'd1', 'd2', 'd3'], 'col2': [1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1], 'col3': [-1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1]}
df = pd.DataFrame(d)
df
    col1    col2    col3
0   a1       1      -1
1   a2       1      -1
2   a3       1       1
3   b1      -1      -1
4   b2      -1      -1
5   b3      -1       1
6   c1      -1       1
7   c2       1       1
8   c3       1       1
9   d1      -1      -1
10  d2       1      -1
11  d3       1       1

我想能够拔出只有那些行,其中col3 == 1首次n后行col2 == 1首次,每个字母组。

因此,例如,如果我们正在寻找 col2 变为 1 后一行col3 变为 1 的时间(对于每个字母组),我们将得到

    col1    col2    col3
0   d3      1       1

因为对于d组来说,col2 在 d2 时从 -1 变为 1,而 col3 在 d3 时从 -1 变为 1。 而这在任何其他组中都没有发生过。

如果我们想要在 col2 变为 1 后两行col3 变为 1 的(对于每个字母组),我们将得到

    col1    col2    col3
0   a3      1       1

因为对于组 col2 在 a1 处以 1 开始,而 col3 在 a3 处从 -1 变为 1。

编辑:

这是我笨拙的做法……有人有更优雅的解决方案吗?

df['newCol'] = (
           (((df['col2'].shift(n+1).isnull() | (df['col2'].shift(n+1) == -1)) &
           (df['col2'].shift(n+1).isnull() | (df['col2'].shift(n+1) == -1))) |
           (df['col1'].shift(n+1).str[0] != df['col1'].str[0])) &
           (df['col2'].shift(n) == 1) &
           (df['col3'].shift(n) == -1) &
           (df['col2'].shift(1) == 1) &
           (df['col3'].shift(1) == -1) &
           (df['col2'] == 1) &
           (df['col3'] == 1) &
           (df['col1'].shift(n).str[0] == df['col1'].str[0])) if n > 0 \
            else \
           ((((df['col2'].shift(n+1).isnull() | (df['col2'].shift(n+1) == -1)) &
           (df['col2'].shift(n+1).isnull() | (df['col2'].shift(n+1) == -1))) |
           (df['col1'].shift(n+1).str[0] != df['col1'].str[0])) &
           (df['col2'] == 1) &
           (df['col3'] == 1))
    

将我的最后一条评论放入答案中。 使用n创建一个滞后的新列,然后只需过滤标准方式并获取col1的第一个值。

n = 2
df['newCol'] = df['col2'].shift(n)
df.loc[(df['col3'] == 1) & (df['newCol'] == 1), ['col1']].values[0]

您可以将其包装到一个函数中并使所有内容都成为参数。

尝试这个:

n=2
cond = pd.concat([(df['col2'] == 1).groupby(df['col1'].str[0]).cumsum().shift(n),
                  (df['col3'] == 1).groupby(df['col1'].str[0]).cumsum()], 
                 axis=1)\
         .eq(1)\
         .all(axis=1)
df[cond]

输出:

  col1  col2  col3
2   a3     1     1

或者更简单地说,我认为:

cond1 = (df['col2'] == 1).groupby(df['col1'].str[0]).cumsum().shift(n) == 1
cond2 = (df['col3'] == 1).groupby(df['col1'].str[0]).cumsum() == 1
df[cond1 & cond2]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM