Как создать вектор данных pandas с значениями, основанными на групповом - PullRequest
1 голос
/ 17 марта 2020

с учетом следующих данных:

x1 = 'one'
x2 = 'two'
x3 = 'three'
y1 = 'yes'
y2 = 'no'
n = 3


df = pd.DataFrame(dict(
    a = [x1]*n + [x2]*n + [x3]*n,
    b = [
        y1,
        y1,
        y2,
        y2,
        y2,
        y2,
        y2,
        y2,
        y1,
    ]
))

, которые выглядят так:

Out[5]:
       a    b
0    one  yes
1    one  yes
2    one   no
3    two   no
4    two   no
5    two   no
6  three   no
7  three   no
8  three  yes

Я хочу знать, возможно ли создать столбец c следующим образом:

Out[5]:
       a    b   c
0    one  yes   1
1    one  yes   1
2    one   no   1
3    two   no   0
4    two   no   0
5    two   no   0
6  three   no   1
7  three   no   1
8  three  yes   1

, где c определяется как 1, если для группы в a столбец b содержит yes

Я попытался сделать следующее:

group_results = df.groupby('a').apply(lambda x:  'yes' in x.b.to_list() )
group_results = group_results.reset_index()
group_results = group_results.rename(columns = {0 : 'c'})
df = pd.merge(df, group_results, left_on = 'a', 
                  right_on = 'a', 
                  how = 'left').copy()

Но я чувствую, что есть лучший подход.

Ответы [ 2 ]

2 голосов
/ 17 марта 2020

Используйте Series.isin для групп с хотя бы одним столбцом yes в a, последнее преобразование маски в целые числа с Series.view:

df['c'] = df['a'].isin(df.loc[df['b'].eq('yes'), 'a']).view('i1')
print(df)
       a    b  c
0    one  yes  1
1    one  yes  1
2    one   no  1
3    two   no  0
4    two   no  0
5    two   no  0
6  three   no  1
7  three   no  1
8  three  yes  1

Деталь :

print(df.loc[df['b'].eq('yes'), 'a'])
0      one
1      one
8    three
Name: a, dtype: obje
2 голосов
/ 17 марта 2020

IIU C, вы можете использовать Groupby+transform с any после группировки по условной серии, которая проверяет, если df['b'] equals 'yes' и цепочка либо astype(int), либо view для целочисленного представления

df['c'] = df['b'].eq('yes').groupby(df['a']).transform('any').view('i1')
print(df)

       a    b  c
0    one  yes  1
1    one  yes  1
2    one   no  1
3    two   no  0
4    two   no  0
5    two   no  0
6  three   no  1
7  three   no  1
8  three  yes  1
...