Создание частотного словаря из кадра данных Pandas без зацикливания - PullRequest
0 голосов
/ 24 июня 2019

Мне нужно сделать частотный словарь из серии панд (из столбца 'amin_acid' в приведенном ниже кадре данных), который также добавляет смежную строку для каждой записи в словаре (из столбца "шаблоны").

    templates   amino_acid
0   118       CAWSVGQYSNQPQHF
1   635       CASSLRGNQPQHF
2   468       CASSHGTAYEQYF
3   239       CASSLDRLSSGEQYF
4   51        CSVEDGPRGTQYF

Мой нынешний подход итерации по фрейму данных кажется неэффективным и даже анти-паттерном согласно этого поста . Как я могу улучшить эффективность / использовать лучшие практики для этого?

Мой текущий подход:

sequence_counts = {}
seqs = list(zip(df.amino_acid, df.templates))

for seq in seqs:
    if seq[0] not in sequence_counts:
        sequence_counts[seq[0]] = 0
    sequence_counts[seq[0]] += seq[1]

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

sequence_counts = df['amino_acid'].value_counts().to_dict()

Любая помощь / обратная связь будет принята с благодарностью! :)

Ответы [ 2 ]

0 голосов
/ 24 июня 2019

Только что протестировал код комментария @Nolan Conaway, и лучше всего это сделать:

df.groupby('amino_acid').templates.sum()

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

Для скорости я измерил прошедшее время в кадре данных 10 ^ 4, и этот код примерно на три порядка быстрее (0,007 против 4,3 секунды), чем мой ответ ниже.

Нолан должен поместить комментарий в ответ, чтобы он мог быть зачислен его аккуратным и умным использованием pandas dataframe api.

Я оставлю здесь свой ответ на всякий случай, если кто-то найдет комментарии полезными.

Я не знаю pandas api полностью, но я не могу найти какую-либо комбинацию api, которая бы получила то, что вам нужно (но Нолан сделал!). Но кажется, что вы можете значительно улучшить свой код, не создавая список или явно архивируя данные. Если вы используете итераторы вместо этих структур, вы можете улучшить производительность.

Например, в list(zip(df.amino_acid, df.templates)), list не является действительно необходимым, потому что zip уже возвращает список. Кроме того, вы можете использовать функцию izip библиотеки itertools, которая дает итератор без построения списка. Кроме того, лучше использовать конструкторы итераторов pandas вместо вызова столбцов (что, насколько я понимаю, будет также возвращать копию данных в списке, поэтому у вас есть еще одна итерация над фреймом данных).

В любом случае, я бы попробовал что-то подобное.

sequence_counts = { }
for _, row in df.iterrows():
    t, aa = row['templates'], row['amino_acid']
    s = sequence_counts.get(aa, 0)
    sequence_counts[aa] = s + t

Таким образом, вы действительно перебираете данные только один раз, с итератором, который дает вам фрейм данных.

0 голосов
/ 24 июня 2019

Насколько я понимаю из вашего вопроса, вы хотите создать словарь ключ / значение, такое что key=amino_acid и value is the frequency = templates

Поскольку вы успешно создали кортежи с seqs = list(zip(df.amino_acid, df.templates))

Ваш словарь может быть построен как:

sequence_counts = dict(seqs)

в одну строку:

sequence_counts = dict(zip(df.amino_acid, df.templates))

или вы можете сделать что-то из этой природы:

sequence_counts = dict([(k,v) for k,v in zip(df.amino_acid,df.templates)])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...