【问题标题】:Group pandas dataframe in unusual way以不寻常的方式对熊猫数据框进行分组
【发布时间】:2021-01-15 05:23:14
【问题描述】:

问题

我有以下 Pandas 数据框:

    data = {
        'ID':  [100, 100, 100, 100, 200, 200, 200, 200, 200, 300, 300, 300, 300, 300],
        'value': [False, False, True, False, False, True, True, True, False, False, False, True, True, False],
    }
    df = pandas.DataFrame (data, columns = ['ID','value'])

我想获得以下组:

  • 第 1 组:对于每个 ID,所有 False 行,直到该 ID 的第一个 True 行
  • 第 2 组:对于每个 ID,该 ID 的最后一个 True 行之后的所有 False 行
  • 第 3 组:所有真实行

这可以用 pandas 完成吗?

我尝试过的

我试过了

group = df.groupby((df['value'].shift() != df['value']).cumsum())

但这会返回错误的结果。

【问题讨论】:

  • - 第 1 组:对于每个 ID,所有 False 行,直到该 ID 的第一个 True 行。 - 第 2 组:对于每个 ID,该 ID 的最后一个 True 行之后的所有 False 行。 - 第 3 组:所有真实行。
  • 你在True之间有没有False

标签: python pandas pandas-groupby


【解决方案1】:

让我们尝试按照你的逻辑:

# 1. all False up to first True
group1 = df.loc[df.groupby('ID')['value'].cumsum() == 0]

# 2. all False after last True
group2 = df.loc[df.iloc[::-1].groupby('ID')['value'].cumsum()==0]

# 3. all True
group3 = df[df['value']]

输出:

    ID      value
0   100     False
1   100     False
4   200     False
9   300     False
10  300     False

    ID      value
3   100     False
8   200     False
13  300     False

    ID      value
2   100     True
5   200     True
6   200     True
7   200     True
11  300     True
12  300     True

【讨论】:

    【解决方案2】:

    这适用于您的示例数据

    df['groups'] = df.groupby('ID').value.apply(lambda x: x.diff().ne(False).cumsum()).astype('int')
    for _,df_groups in df.groupby('groups'):
      print(df_groups)
      print('-'*20)
    

    输出:

         ID  value  groups
    0   100  False       1
    1   100  False       1
    4   200  False       1
    9   300  False       1
    10  300  False       1
    --------------------
         ID  value  groups
    2   100   True       2
    5   200   True       2
    6   200   True       2
    7   200   True       2
    11  300   True       2
    12  300   True       2
    --------------------
         ID  value  groups
    3   100  False       3
    8   200  False       3
    13  300  False       3
    --------------------
    

    【讨论】:

      【解决方案3】:

      让我们尝试shift + cumsum 创建 groupby 键:顺便说一句,我真的很喜欢你显示预期输出的方式

      s = df.groupby('ID')['value'].apply(lambda x : x.ne(x.shift()).cumsum())
      d = {x : y for x ,y in df.groupby(s)}
      d[2]
           ID  value
      2   100   True
      5   200   True
      6   200   True
      7   200   True
      11  300   True
      12  300   True
      d[1]
           ID  value
      0   100  False
      1   100  False
      4   200  False
      9   300  False
      10  300  False
      d[3]
           ID  value
      3   100  False
      8   200  False
      13  300  False
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-02-07
        • 2022-01-25
        • 1970-01-01
        • 1970-01-01
        • 2017-10-15
        • 2013-07-30
        • 1970-01-01
        • 2021-11-02
        相关资源
        最近更新 更多