【问题标题】:Error: None of [Index(['...'], dtype='object')] are in the [index]错误:[Index(['...'], dtype='object')] 中没有一个在 [index] 中
【发布时间】:2020-04-12 10:29:55
【问题描述】:

我正在尝试根据以下条件删除 pandas 中的一组分组行:

如果一个组(按 col1 分组)在 col2 中有超过 2 个值 'c',则删除整个组。

我的样子是这样的

  col1  col2                       
0  A     10:10 
1  A     20:05
2  A     c
3  A     00:10
4  B     04:15
2  B     c
3  B     c
4  B     13:40

我正在努力到达这里:

  col1  col2                       
0  A     10:10 
1  A     20:05
2  A     c
3  A     00:10

通常我会为其他非常相似的数据框执行此操作(并且它有效):

df = df.groupby('col1').filter(lambda x: x["col2"].value_counts()[['c']].sum() < 2)

但是对于这个不起作用,我收到此错误:

KeyError: "None of [Index(['c'], dtype='object')] are in the [index]"

有人知道我该怎么做吗?

谢谢!

【问题讨论】:

    标签: python pandas dataframe pandas-groupby


    【解决方案1】:

    我建议用于提高性能boolean indexing

    df = df[df['col2'].eq('c').groupby(df['col1']).transform('sum').lt(2)]
    print (df)
      col1   col2
    0    A  10:10
    1    A  20:05
    2    A      c
    3    A  00:10
    

    详情

    首先比较Series.eq== 的值:

    print (df['col2'].eq('c'))
    0    False
    1    False
    2     True
    3    False
    4    False
    2     True
    3     True
    4    False
    Name: col2, dtype: bool
    

    然后按GroupBy.transformsum 计算每个组的True 值,Trues 正在像1 一样处理:

    print (df['col2'].eq('c').groupby(df['col1']).transform('sum'))
    0    1.0
    1    1.0
    2    1.0
    3    1.0
    4    2.0
    2    2.0
    3    2.0
    4    2.0
    Name: col2, dtype: float64
    

    最后按Series.lt 过滤以获得更少:

    print (df['col2'].eq('c').groupby(df['col1']).transform('sum').lt(2))
    0     True
    1     True
    2     True
    3     True
    4    False
    2    False
    3    False
    4    False
    Name: col2, dtype: bool
    

    【讨论】:

      【解决方案2】:

      这是另一种使用loc 创建临时数据帧的方法,该数据帧获取按“col1”分组的“col2”中“c”值的计数,并将计数“.isin() 过滤“col1”组,如果它们被标记为临时数据帧/列表“dft”中每个组的“c”计数少于 2 个的列:

      dft = df.loc[df['col2'] == 'c'].groupby('col1').count().reset_index()
      dft = dft.loc[dft['col2'] < 2, 'col1'].to_list()
      df = df.loc[df['col1'].isin(dft)]
      df
      

      【讨论】:

        【解决方案3】:

        你可以使用 len:

        df.groupby('col1').filter(lambda x: len(x.loc[x.col2.eq('c')])<2)
        
            col1    col2
        0   A   10:10
        1   A   20:05
        2   A   c
        3   A   00:10
        

        您的解决方案实际上也适用于我:

        df.groupby('col1').filter(lambda x: x["col2"].value_counts()[['c']].sum() < 2)
        

        如果还是不行,可以试试下面的方法看看是否有帮助。

        df.astype(str).groupby('col1').filter(lambda x: x["col2"].value_counts()[['c']].sum() < 2)
        

        【讨论】:

        • 第二个和第三个选项我收到相同的KeyError: "None of [Index(['c'], dtype='object')] are in the [index]" 错误。第一个运行良好,但只是删除带有“c”的行而不是整个组。我会尝试改变一点。我知道这很奇怪,因为对于 非常 类似的 df 它可以正常工作。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-11-18
        • 2019-09-03
        • 2021-01-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-06
        相关资源
        最近更新 更多