Если у нас есть следующие входные данные, и мы хотели бы сохранить строки, если их «столбец APPID» (4-й столбец) одинаков, а их столбец «Категория» (18-й столбец) — это одна «Клетка» и одна «Биохимическая» или одна «Клетка» и один «Фермент».
A , APPID , C , APP_ID , D , E , F , G , H , I , J , K , L , M , O , P , Q , Категория , S , T
,,, APP-1 ,, ,,,,,,,,,,,, Cell ,,
,,, APP-1 ,,,,,,,,,,,,,, Enzyme ,,
,,, APP-2 ,,,,,,,,,,,,, Cell ,,
,,, APP-3 ,,,,,,,,,,,,,, Cell ,,
,,, APP -3,,,,,,,,,,,,,,Биохим,,
Идеальный выход будет
A , APPID , C , APP_ID , D , E , F , G , H , I , J , K , L , M , O , P , Q , Категория , S , T
,,, APP-1 ,, ,,,,,,,,,,,, Фермент,,
,,, АРР-3 ,,,,,,,,,,,,,,, Биохимический ,,
,,, АРР-1 ,,,,,,,,,,,,, Cell ,,
,,, APP-3 ,,,,,,,,,,,,,, Cell ,,
«APP-1» сохраняется, потому что их столбец 3 одинаков, а их категория - одна «Клетка», а другая - «Фермент». То же самое для «АРР-3», у которого в столбце «Категория» одна «Клетка», а другая «Биохимическая».
Следующая попытка может помочь:
import os
App=["1"]
for a in App:
outname="App_"+a+"_target_overlap.csv"
out=open(outname,'w')
ticker=0
cell_comp_id=[]
final_comp_id=[]
# make compound with cell activity (to a target) list first
filename="App_"+a+"_target_Detail_average.csv"
if os.path.exists(filename):
file = open (filename)
line=file.readlines()
if(ticker==0): # Deal with the title
out.write(line[0])
ticker=ticker+1
for c in line[1:]:
c=c.split(',')
if(c[17]==" Cell "):
cell_comp_id.append(c[3])
else:
cell_comp_id=list(set(cell_comp_id))
# while we have list of compounds with cell activity, now we search the Bio and Enz and make one final compound list
if os.path.exists(filename):
for c in line[1:]:
temporary_line=c #for output_temp
c=c.split(',')
for comp in cell_comp_id:
if (c[3]==comp and c[17]==" Biochemical "):
final_comp_id.append(comp)
out.write(str(temporary_line))
elif (c[3]==comp and c[17]==" Enzyme "):
final_comp_id.append(comp)
out.write(str(temporary_line))
else:
final_comp_id=list(set(final_comp_id))
# After we obatin a final compound list in target a , we go through all the csv again for output the cell data
filename="App_"+a+"_target_Detail_average.csv"
if os.path.exists(filename):
for c in line[1:]:
temporary_line=c #for output_temp
c=c.split(',')
for final in final_comp_id:
if (c[3]==final and c[17]==" Cell "):
out.write(str(temporary_line))
out.close()
Когда входной файл небольшой (десятки тысяч строк), этот скрипт может закончить свою работу за разумное время. Однако входные файлы становятся миллионами или миллиардами строк, этот скрипт будет выполняться вечно (дни...). Я думаю, проблема в том, что мы создаем список APPID с «Cell» в 18-м столбце. Затем мы возвращаемся, чтобы сравнить этот список «Ячейка» (возможно, полмиллиона строк) со всем файлом (например, 1 миллион строк): Если какой-либо APPID в списке ячеек и весь файл одинаковый и 18-й столбец строки в целом файле «Фермент» или «Биохимический», мы сохраняем информацию. Этот шаг кажется очень трудоемким.
Я вот думаю, может быстрее подготовить словари "Клетка", "Фермент" и "Биохимический" и сравнить их? Могу ли я узнать, есть ли у какого-нибудь гуру лучший способ его обработки? Любой пример/комментарий будет полезен. Спасибо.
- Мы используем питон 2.7.6.
final_comp_id=list(set(final_comp_id))
и другое подобное мне непонятны. Возможно, это из-за неправильного отступа. Похоже, вы конвертируете пустой список обратно в пустой список. Это ваше намерение? - person pts   schedule 07.08.2014billion of lines
может перегрузить даже самый оптимизированный код на обычном компьютере. - person Andrew Johnson   schedule 07.08.2014final_comp_id=list(set(final_comp_id))
иif(ticker==0):
, что всегда верно) кажутся мне ненужными. Не могли бы вы перепроверить, что они действительно не нужны, и удалить их? Это не сделает его быстрее, но улучшит мое понимание этого. Кроме того, пожалуйста, избегайте.readlines()
, как предложил Дэниел в своем ответе. Если код все еще работает медленно, опубликуйте новую версию, в противном случае примите ответ Дэниела. - person pts   schedule 07.08.2014