【问题标题】:How can I remove the item in list using the comparison between list and index in pandas?如何使用熊猫中列表和索引之间的比较来删除列表中的项目?
【发布时间】:2018-12-20 10:03:33
【问题描述】:

这是我的数据框:

Cites_Dogs  Dog_Number
DOG45555    DOG123
DOG127      DOG123
DOG7760     DOG126
DOG45       DOG126
DOG559      DOG126
DOG760      DOG126
DOG123      DOG127
DOG789      DOG127
DOG860      DOG127

我已通过此代码转换为列表:

all_cites_dog = all_cites_dog.groupby('Dog_Number')['Cites_Dogs'].apply(list)

我想删除列表中与索引DOG123DOG126DOG127不匹配的项目。

DOG123   [ 'DOG45555' ,  'DOG127']
DOG126   [ 'DOG7760', 'DOG456' ,  'DOG559' ,  'DOG760']
DOG127   [ 'DOG123' ,  'DOG789' ,  'DOG860']

我希望看到这样的结果:

DOG123   [ 'DOG127']
DOG126   ['']
DOG127   [ 'DOG123']

我应该怎么做TT?

【问题讨论】:

    标签: python pandas dataframe pandas-groupby


    【解决方案1】:

    您可以按照大致步骤:

    1. 根据Cites_Dogs过滤您的数据框。
    2. 执行groupby + applylist
    3. 根据唯一的狗编号重新索引您的数据框。
    4. NaN 值替换为空列表以保持一致性。

    这是一个演示:

    unq_dogs = df['Dog_Number'].unique()
    
    res = df.loc[df['Cites_Dogs'].isin(unq_dogs]\
            .groupby('Dog_Number')['Cites_Dogs'].apply(list)\
            .reindex(unq_dogs)\
            .fillna(pd.Series([[] for _ in range(len(unq_dogs))], index=unq_dogs))\
            .reset_index()
    
    print(res)
    
      Dog_Number Cites_Dogs
    0     DOG123   [DOG127]
    1     DOG126         []
    2     DOG127   [DOG123]
    

    【讨论】:

      【解决方案2】:

      您可以使用apply 并使用列表推导将元素保留在索引中:

      l = all_cites_dog.index
      all_cites_dog.apply(lambda x: [i for i in x if i in l])
      
      Dog_Number
      DOG123    [DOG127]
      DOG126          []
      DOG127    [DOG123]
      Name: Cites_Dogs, dtype: object
      

      【讨论】:

        【解决方案3】:

        groupby+apply中使用过滤:

        idx = set(all_cites_dog['Dog_Number'])
        all_cites_dog = (all_cites_dog.groupby('Dog_Number')['Cites_Dogs']
                                     .apply(lambda x: list([y for y in x if y in idx])))
        
        print (all_cites_dog)
        Dog_Number
        DOG123    [DOG127]
        DOG126          []
        DOG127    [DOG123]
        Name: Cites_Dogs, dtype: object
        

        为了获得更好的性能,首先按boolean indexingisin 过滤,然后groupby,最后添加缺少的不匹配的空值:

        s = (all_cites_dog[all_cites_dog['Cites_Dogs'].isin(all_cites_dog['Dog_Number'].unique())]
                     .groupby('Dog_Number')['Cites_Dogs']
                     .apply(list))
        
        idx = np.setdiff1d(all_cites_dog['Dog_Number'].unique(), s.index)
        s1 = pd.Series([[]] * len(idx), index=idx)
        print (s1)
        DOG126    []
        dtype: object
        
        s = s.append(s1).sort_index()
        print (s)
        DOG123    [DOG127]
        DOG126          []
        DOG127    [DOG123]
        dtype: object
        

        【讨论】:

          【解决方案4】:

          您可以过滤 isin 支票。

          (df.set_index('Dog_Number')
             .query("Cites_Dogs in index")
             .reindex(df.Dog_Number.unique()))
          
                     Cites_Dogs
          Dog_Number           
          DOG123         DOG127
          DOG126            NaN
          DOG127         DOG123
          

          如果需要进一步减少,可以链接groupby

          (df.set_index('Dog_Number')
             .query("Cites_Dogs in index")
             .reindex(df.Dog_Number.unique())
             .groupby(level=0)['Cites_Dogs']
             .apply(pd.Series.tolist))
          
          Dog_Number
          DOG123    [DOG127]
          DOG126       [nan]
          DOG127    [DOG123]
          Name: Cites_Dogs, dtype: object
          

          另一个选项是 groupbyapply 设置成员资格检查。

          s = set(df.Dog_Number)
          df.groupby('Dog_Number').Cites_Dogs.apply(lambda x: x[x.isin(s)].tolist())
          
          Dog_Number
          DOG123    [DOG127]
          DOG126          []
          DOG127    [DOG123]
          Name: Cites_Dogs, dtype: object
          

          【讨论】:

            【解决方案5】:

            试试这是否只适用于一种衬垫解决方案:

            df = pd.DataFrame({'Cites_Dogs':  ['DOG45555' ,'DOG127' , 'DOG7760' ,'DOG45','DOG559','DOG760','DOG123','DOG789','DOG860'],
                           'Dog_Number': ['DOG123', 'DOG123', 'DOG126', 'DOG126', 'DOG126', 'DOG126', 'DOG127', 'DOG127', 'DOG127']})
            a = ['DOG123', 'DOG126', 'DOG127']
            
            df['Cites_Dogs'][~df['Cites_Dogs'].isin(a)] = np.nan
            
            df.replace([np.nan], '', inplace=True)
            
            df = df.groupby('Dog_Number')['Cites_Dogs'].apply(list)
            
            # and output looks like this
            Dog_Number
            DOG123      [, DOG127]
            DOG126        [, , , ]
            DOG127    [DOG123, , ]
            Name: Cites_Dogs, dtype: object
            

            谢谢!

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2022-06-15
              • 2021-10-14
              • 2021-12-09
              • 1970-01-01
              • 2021-03-12
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多