Подмножество pandas dataframe в нескольких столбцах на основе значений из другого dataframe - PullRequest
0 голосов
/ 30 ноября 2018

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

import pandas as pd
points = pd.DataFrame({'player':['a','b','c','d','e'],'points':[2,5,3,6,1]})
matches = pd.DataFrame({'p1':['a','c','e'], 'p2':['c', 'b', 'd']})

Я хочу сохранить только те строки из совпадений фреймов данных, где точки p1 и p2 имеют значения больше 2. Сейчас я сначала объединяю точки и совпадения на p1 иЗатем игрок объединяет полученный фрейм данных и точки на p2 и player.После этого применяем фильтр к обеим точкам столбцов результирующего кадра данных.

new_df = pd.merge(matches, points, how = 'left', left_on = 'p1', right_on = 'player')
new_df = pd.merge(new_df, points, how = 'left', left_on = 'p2', right_on = 'player')
new_df = new_df[(new_df.points_x >2) & (new_df.points_y >2)]

Это дает мне то, что мне нужно, но мне было интересно, что будет лучшим и эффективным способом сделать это?

Ответы [ 2 ]

0 голосов
/ 30 ноября 2018

В качестве альтернативы вы можете построить ряд игроков, сопоставляющих очки, затем использовать pd.Series.map для каждой серии в matches:

s = points.set_index('player')['points']
res = matches.loc[matches.apply(lambda x: x.map(s)).gt(2).all(1)]

print(res)

  p1 p2
1  c  b
0 голосов
/ 30 ноября 2018

Я бы избегал объединений в этом случае и написал бы это так:

scorers = points.query('points > 2').player
matches.query('p1 in @scorers and p2 in @scorers')

Я думаю, что это более читабельно.

Это немного глупо для сравнения на таком маленьком примере, но на моей машине этот метод работает в среднем за 2,99 мс, в то время как ваш оригинальный метод занимает 4,45 мс.Было бы интересно узнать, лучше ли это масштабируется или нет.

Я не знаю, есть ли другие микрооптимизации, которые вы могли бы сделать для этого кода, такие как преобразование scorers в набор.

Если вам не нравится синтаксис query:

scorers = points[points.points > 2].player
matches[matches.p1.isin(scorers) & matches.p2.isin(scorers)]

Это также повышает производительность, занимая около 1,36 мс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...