У меня есть фрейм данных

df = pd.DataFrame({'id':['one','one','two','two','three','three','three'],
                   'type':['current','saving','current','current','current','saving','credit']})

Я хотел бы посчитать количество идентификаторов, которые имеют только «текущий», что-то должно понравиться:

only_currnt_id_list = ['two']
1
KEXIN WANG 30 Авг 2017 в 16:44

3 ответа

Лучший ответ

Попробуйте это с помощью pd.crosstab

df=pd.crosstab(df.id,df.type)
df.loc[df.sum(1)==df.current,].index.values[0]

Out[1065]: 'two'

Или вы можете использовать groupby и nunique

df['unique']=df.groupby('id')['type'].transform('nunique')

df.loc[(df.unique==1)&(df.type=='current'),:].id.unique().tolist()


Out[1085]: ['two']
1
YOBEN_S 30 Авг 2017 в 14:07

Я думаю, что вам нужно:

L = df.groupby('id') \
      .filter(lambda x: (x['type'] == 'current').all() and 
                        (x['type'] == 'current').sum() == 1)['id'].tolist()
print (L)

['two']

РЕДАКТИРОВАТЬ:

df = pd.DataFrame({'id':['one','one','two','three','three','three'],'type':['current','current','current','current','saving','credit']})
print (df)
      id     type
0    one  current
1    one  current
2    two  current
3  three  current
4  three   saving
5  three   credit

L = df.groupby('id') \
      .filter(lambda x: (x['type'] == 'current').all() and 
                        (x['type'] == 'current').sum() == 1)['id'].tolist()
print (L)
['two']

L = df.groupby('id') \
      .filter(lambda x: (x['type'] == 'current').all())['id'].unique().tolist()
print (L)
['one', 'two']
2
jezrael 30 Авг 2017 в 14:01

Не используя чистых панд, но вы можете просто использовать разницу set между всеми идентификаторами и идентификаторами, которые имеют type != 'current':

>>> set(df["id"]) - set(df["id"][df["type"] != "current"])
{2}
0
tobias_k 30 Авг 2017 в 13:51