Сила numpy / scipy / pandas заключается в использовании кода C для выполнения большей части работы за вас. Учитывая, что, по вашим словам, есть 300 тыс. Строк и 80 столбцов, я предлагаю вам сначала приложить все усилия, чтобы убедиться, что вы обрабатываете строки в C, а не в python. Таким образом, ваш первый цикл должен быть исключен: не обрабатывайте 300k элементов, используя python.
Как я читаю ваши требования, у вас есть индекс (метки строк), в котором есть значения какого-то типа, которые могут отображаться в отдельных ячейках других ваших столбцов. Примерно так:
Index A B C D
1 0 0 3 0
2 2 0 1 -1
3 0 0 0 0
192 0 0 1 -1
Вы хотите знать, для каждого индекса, есть ли это значение в каком-либо из столбца A, столбца B, столбца C и т. Д. Если любой Значение индекса отображается в столбце, этот столбец имеет значение «ALIVE». ».
В конце процесса столбцы либо ALIVE, либо нет, и затем вы хотите отфильтровать другой словарь, чтобы исключить столбцы, которые не являются ALIVE.
В моем примере выше столбец A считается живым из-за {2}, а столбец C считается живым из-за {3, 1}, но столбцы B и D не являются живыми, потому что они не содержат значений, которые присутствуют в указателе. Это правильно?
Попробуйте использовать isin
, чтобы определить, присутствуют ли значения в столбцах в индексе. Затем используйте any
, чтобы свести логические результаты к одному логическому значению, которое определяет, является ли столбец живым:
row_labels = df.index
col_is_alive = df.isin(row_labels).any() # NB: any(index=0) is default
(ПРИМЕЧАНИЕ. Я не в том месте, где я могу запустить этот код. Он может содержать синтаксис или другие ошибки.)
Теперь у вас есть серия из 80 логических значений, сообщающих, какие столбцы живы. Вы можете делать обработку, как вам нравится.
alive_col_names = { name for name in df.columns if col_is_alive[name] } # Set comprehension
Тем не менее, ваше первоначальное постановка задачи звучит так, будто вы делаете это один раз (в отличие от итеративного обновления групп имен столбцов). В этом случае, вместо того, чтобы пересекать значения словаря (списки каждого имени столбца, кроме ключа), я бы предложил просто вычислить значения напрямую. То есть вычислять пары ключ-> значение напрямую, а не пытаться «пересекать» списки значений с этим списком всех имен столбцов.
col_dict = { key:alive_col_names - {key} for key in alive_col_names}
С другой стороны, если вы каким-то образом итеративно обновляете эти значения, я бы посоветовал вам сделать вашу вторую структуру данных словарем строки -> установить вместо строки -> список, поскольку это даст вам доступ к стандарту установить операции и поведение.
new_col_dict = {}
for key, other_cols in col_dict.items():
if key not in alive_col_names:
continue
new_col_dict[key] = other_cols.interset(alive_col_names)
col_dict = new_col_dict
(Который можно свернуть, используя сложное понимание, но, возможно, не следует в интересах читабельности.)