如果值是多个,熊猫会在一个组中删除值

sha*_*aia 7 pandas pandas-groupby

我有一个带有一id列和一quantity列的数据框,可以是 0 或 1。

import pandas as pd

df = pd.DataFrame([
{'id': 'thing 1', 'date': '2016-01-01', 'quantity': 0 },
  {'id': 'thing 1', 'date': '2016-02-01', 'quantity': 0 },
  {'id': 'thing 1', 'date': '2016-09-01', 'quantity': 1 },
  {'id': 'thing 1', 'date': '2016-10-01', 'quantity': 1 },
  {'id': 'thing 2', 'date': '2017-01-01', 'quantity': 1 },
  {'id': 'thing 2', 'date': '2017-02-01', 'quantity': 1 },
  {'id': 'thing 2', 'date': '2017-02-11', 'quantity': 1 },
  {'id': 'thing 3', 'date': '2017-09-01', 'quantity': 0 },
  {'id': 'thing 3', 'date': '2017-10-01', 'quantity': 0 },
])
df.date = pd.to_datetime(df.date, format="%Y-%m-%d")
df
Run Code Online (Sandbox Code Playgroud)

如果id我有 0 和 1 值,我只想返回 1。如果我只有 1 个,我想全部返回。如果我只有 0,我想返回所有这些。

我这样做的方法是对每个组应用一个函数,然后重置索引:

def drop_that(dff):
    q = len(dff[dff['quantity']==1])
    if q >0:
        return dff[dff['quantity']==1]
    else:
        return dff
    
dfg = df.groupby('id', as_index=False).apply(drop_that)
dfg.reset_index(drop=True)
Run Code Online (Sandbox Code Playgroud)

然而,我只是通过强力谷歌搜索来实现这一点,我真的不知道这是否是一个好的 Pandas 实践,或者是否有其他方法会更高效。

任何建议将不胜感激。

Qua*_*ang 6

你可以试试:

# find the number of unique quantity for each thing
s = df.groupby('id')['quantity'].transform('nunique')


df[s.eq(1)                 # things with only 1 quantity value (either 0 or 1)
   | df['quantity'].eq(1)  # or quantity==1 when there are 2 values
  ]
Run Code Online (Sandbox Code Playgroud)

输出:

        id       date  quantity
2  thing 1 2016-09-01         1
3  thing 1 2016-10-01         1
4  thing 2 2017-01-01         1
5  thing 2 2017-02-01         1
6  thing 2 2017-02-11         1
7  thing 3 2017-09-01         0
8  thing 3 2017-10-01         0
Run Code Online (Sandbox Code Playgroud)


WeN*_*Ben 5

根据您的逻辑,尝试transform使用max,如果 max eq 为原始值,我们应该保持,

#logic : only have 0 or 1  max will be 0 or 1 , 
#        if both have 0 and 1, max should be 1 we should keep all value eq to 1 

out = df[df.quantity.eq(df.groupby('id')['quantity'].transform('max'))]
Out[89]: 
        id       date  quantity
2  thing 1 2016-09-01         1
3  thing 1 2016-10-01         1
4  thing 2 2017-01-01         1
5  thing 2 2017-02-01         1
6  thing 2 2017-02-11         1
7  thing 3 2017-09-01         0
8  thing 3 2017-10-01         0
Run Code Online (Sandbox Code Playgroud)