Векторизация сравнения между списком и списком списков в пандах - PullRequest
0 голосов
/ 10 мая 2019

У меня есть два pd.DataFrames классы и учителя .

классы DataFrame содержат помимо прочего переменные классы ['no-pupils'] и классы ['учителя'] .Первый - это целое число (количество учащихся), а второй - список строк, так как в каждом классе может быть несколько учителей.

учителя DataFrame имеет (помимо других) две переменные.Первый - это учителя ['имя'] , что соответствует классам ['учителя'] пунктов списка, второй - учителя ['без учеников'], которое я хочу вычислить.

Я хочу вычислить это поле, сложив классы ['no-pupils'] всех строк, где классы ['учителя '] содержит учителей [' name '] , чтобы выяснить, сколько учеников взаимодействует с учителем.

Прямо сейчас я делаю это, повторяя цикл for для DataFrame учителей и внутри этого цикла, повторяя классы DataFrame со следующим кодом:

for index-teacher, teacher in teachers.iterrows():
    for index-class, class in classes.iterrows():
        if teacher['name'] in class['teachers']:
            teachers['no-pupils'][index-teacher] = teachers['no-pupils'][index1] + classes['no-pupils'][index-class]

Поскольку у меня примерно2000 строк на DataFrame, это займет 5-10 минут.Поэтому мне интересно, не существует ли более вычислительно эффективного способа использования потрясающих возможностей векторизации от панд.

PS: Если вы удивляетесь странному сценарию использования, я подумал об этом, так как не могу раскрытьреальный случай использования.

1 Ответ

0 голосов
/ 10 мая 2019

Вам не нужно проверять весь фрейм данных для каждого учителя, вы можете просто предварительно обработать его и построить необходимые данные для всех учителей за одну итерацию фрейма данных.Я рекомендую вам использовать Python defaultdicts:

from collections import defaultdict

df = pd.DataFrame({
    'teachers': [['A', 'C'], ['C', 'E'], ['A', 'B', 'C'], ['D'], ['B', 'E']],
    'pupils': [1, 2, 3, 4, 5]
})

t_pupils = defaultdict(int)
for i, row in df.iterrows():
    for teacher in row['teachers']:
        t_pupils[teacher] += row['pupils']
t_pupils

возвращает:

defaultdict(int, {'A': 4, 'B': 8, 'C': 6, 'D': 4, 'E': 7})

Таким образом вы замените квадратичную сложность линейной, что значительно повысит вашу производительность.

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