2016-11-23 7 views
2

У меня есть два списка: один из них - это список из примерно 2 миллионов позиций хромосом (например, [9866, 9899, ​​10257 ....]). Другой - парный список с положением хромосом и pvalue (например, [(9866, 0.001), (9899, ​​0.05)] ...)Найти элементы в списке парных элементов, используя другой список (Python)

Я хотел бы получить значение p для выбранной 2-миллионной хромосомы , Мой код в настоящее время выглядит следующим образом:

Selection = [] 
    for i in selected indices: 
     for x in list(range(len(T3))): 
     if T3[x][0] == i: 
      b = T3[x][0],T3[x][1] 
      Selection.append(b) 

Есть ли самый быстрый способ сделать это? Очевидно, что это очень медленно, так как он выполняет итерацию для каждой строки в T3 и для каждого элемента в выбранных индексах. Я думал об использовании функции набора, но мой список T3 является списком сопряженных элементов

+1

Почему вы используете свой первый список, если у вас есть позиции во втором? Я получил то, что вы хотите сделать. Покажите свой ожидаемый результат – MMF

+1

У меня есть позиция во втором списке, но есть около 1,4 миллиарда позиций, и я хочу только выбрать 2 миллиона из другого списка. – CenCG

+0

Теперь это более понятно ... – MMF

ответ

2

всего, более быстрый подход будет сделать отображение позиции в p-значение:

mapping = dict(T3) 

Тогда используйте это отображение:

selected_pvalues = [mapping[pos] for pos in positions] 

Примечание: mapping удалит все повторяющиеся позиции хромосом и только сохранить последнюю в исходном списке.

+0

T3 - это 1,4 миллиарда записей, должны быть более быстрые методы, чем это, если операция «выбора» должна выполняться только один раз – Adirio

+0

@ juanpa.arrivillaga Спасибо, что отлично поработали! Не забудьте проголосовать, как только у меня будет достаточно репутации. – CenCG

+0

@Adirio Не знаете, почему, но это было на удивление быстрым на самом деле – CenCG

1

Я не уверен, что первый список содержит те же значения, что и первые элементы всех пар во втором (я предполагаю, что они не являются, или нет смысла их иметь).

Вы должны преобразовать список пар в словарь, а затем вы получите каждое значение в (обычно) O (1) сложности выполнения.

Редактировать

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

Измените первый (меньший) список на набор. Затем перейдите по списку пар, и для каждого элемента проверьте, находится ли он в этом наборе. Таким образом, вы по-прежнему будете иметь один проход над большей структурой, но вам потребуется гораздо меньше места.

+0

, так как он может потребовать дублирования записей в списке и потому, что он будет использовать порядок парных списков вместо выбранного порядка элементов, и они могут отличаться. – Adirio

+0

В случаях, которые вы предлагаете (которые Я не уверен, что это требуется OP), мы можем решить это, используя вместо слова set - словарь, чей ключ является позицией и значением, является (списком) индекса (ов) в исходном списке. Это все равно будет гарантировать, что требуемая память меньше по величине. – Mike

0

Было бы лучше сохранить другой идентификатор для хромосом вторых списков. Это позволит вам создать словарь вместо второго списка. Например:

myTrillionsChromosomes = { 
    'chromosomeId': pValue, 
    ... 
} 

Edit: То есть, если вы можете контролировать строительство этих списков. Другой ответ описывает, как преобразовать список кортежей в dictionnary, но при максимальном размере этого списка это может быть не очень мудро.

Тогда вам просто нужно найти значение p в словаре, которое выполняется в постоянное время.

selection = [] 
for id in identifiersList: 
    selection.append((id, myTrillionsChromosomes[id]) 
+1

Удаление комментариев, поскольку они не предоставляют никакой информации сейчас, вы должны сделать то же самое. Downvote также удален. – Adirio

Смежные вопросы