Выбор строк, где условие, заданное столбцом x, истинно для значений в столбце y - PullRequest
0 голосов
/ 28 сентября 2018

У меня есть кадр данных Pandas, который выглядит следующим образом:

Column_X    Column_Y    A-Indicator
   Val1        A           True
   Val1        B           True
   Val2        B           False
   Val2        B           False

Я хочу создать столбец «A-Indicator».Этот столбец имеет значение True для всех строк с Column_X = 'Val1', если одна строка Val1 имеет Column_Y = A. Поскольку ни одна строка с Column_X = 'Val2' не имеет Column_Y = 'A', индикатор A является ложным для всех этих строк,Есть ли простой способ добиться этого?

1 Ответ

0 голосов
/ 28 сентября 2018

Если важна производительность, не используйте groupby:

df['A-Indicator'] = df['Column_X'].isin(df.loc[df['Column_Y'].eq('A'), 'Column_X'].unique())
print (df)
  Column_X Column_Y  A-Indicator
0     Val1        A         True
1     Val1        B         True
2     Val2        B        False
3     Val2        B        False

Объяснение :

Первое сравнение по eq (==):

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

Найти все значения столбца Column_X:

print (df.loc[df['Column_Y'].eq('A'), 'Column_X'])
0    Val1
Name: Column_X, dtype: object

Получить уникальные значения для повышения производительности:

print (df.loc[df['Column_Y'].eq('A'), 'Column_X'].unique())
['Val1']

И последнее сравнение поisin:

print (df['Column_X'].isin(df.loc[df['Column_Y'].eq('A'), 'Column_X'].unique()))
0     True
1     True
2    False
3    False
Name: Column_X, dtype: bool    

Производительность : зависит от количества строк и количества совпадающих значений:

np.random.seed(123)

N = 1000000
L = list('ABCDEFGHIJK')
df = pd.DataFrame({
                      'Column_X':np.random.randint(1000, size=N),
                      'Column_Y': np.random.choice(L, N),
                  })
print (df)

In [193]: %timeit df['A-Indicator'] = df['Column_X'].isin(df.loc[df['Column_Y'].eq('A'), 'Column_X'].unique())
92.1 ms ± 396 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [194]: %timeit df['A-Indicator']=df.groupby('Column_X')['Column_Y'].transform(lambda x: x.isin(['A']).any())
724 ms ± 3.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [195]: %timeit df['A-Indicator']=df.groupby('Column_X')['Column_Y'].transform(lambda x: 'A' in x.unique())
770 ms ± 48.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...