Список фильтров перед записью в CSV в python

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

Это работало хорошо, пока мои данные не стали слишком большими для хранения в оперативной памяти.

Я думаю, что вместо того, чтобы добавлять однорежимный список краев в список, я должен просто записать содержимое folded в CSV и вообще пропустить добавление этих данных в список. Я также хотел бы отфильтровать то, что я пишу в CSV, чтобы записывать только строки с весом больше или равным 2.

Данные:

E1,Brenda Rogers
E1,Evelyn Jefferson
E1,Laura Mandeville
E10,Nora Fayette
E10,Helen Lloyd
E10,Katherina Rogers
E10,Myra Liddel
E10,Sylvia Avondale
E11,Flora Price
E11,Nora Fayette
E11,Helen Lloyd
E11,Olivia Carleton
E12,Nora Fayette
E12,Verne Sanderson
E12,Helen Lloyd
E12,Katherina Rogers
E12,Myra Liddel
E12,Sylvia Avondale
E13,Nora Fayette
E13,Katherina Rogers
E13,Sylvia Avondale
E14,Nora Fayette
E14,Katherina Rogers
E14,Sylvia Avondale
E2,Evelyn Jefferson
E2,Laura Mandeville
E2,Theresa Anderson
E3,Brenda Rogers
E3,Charlotte McDowd
E3,Frances Anderson
E3,Evelyn Jefferson
E3,Laura Mandeville
E3,Theresa Anderson
E4,Brenda Rogers
E4,Charlotte McDowd
E4,Evelyn Jefferson
E4,Theresa Anderson
E5,Brenda Rogers
E5,Charlotte McDowd
E5,Frances Anderson
E5,Evelyn Jefferson
E5,Ruth DeSand
E5,Eleanor Nye
E5,Laura Mandeville
E5,Theresa Anderson
E6,Brenda Rogers
E6,Nora Fayette
E6,Frances Anderson
E6,Evelyn Jefferson
E6,Eleanor Nye
E6,Laura Mandeville
E6,Pearl Oglethorpe
E6,Theresa Anderson
E7,Brenda Rogers
E7,Charlotte McDowd
E7,Nora Fayette
E7,Verne Sanderson
E7,Ruth DeSand
E7,Helen Lloyd
E7,Eleanor Nye
E7,Laura Mandeville
E7,Sylvia Avondale
E7,Theresa Anderson
E8,Brenda Rogers
E8,Verne Sanderson
E8,Frances Anderson
E8,Dorothy Murchison
E8,Evelyn Jefferson
E8,Ruth DeSand
E8,Helen Lloyd
E8,Eleanor Nye
E8,Katherina Rogers
E8,Laura Mandeville
E8,Myra Liddel
E8,Pearl Oglethorpe
E8,Sylvia Avondale
E8,Theresa Anderson
E9,Flora Price
E9,Nora Fayette
E9,Verne Sanderson
E9,Dorothy Murchison
E9,Evelyn Jefferson
E9,Ruth DeSand
E9,Olivia Carleton
E9,Katherina Rogers
E9,Myra Liddel
E9,Pearl Oglethorpe
E9,Sylvia Avondale
E9,Theresa Anderson

Как мне изменить свой код, чтобы он писал напрямую в CSV и не добавлял ребра в свернутый список, а добавлял только те ребра, вес которых больше или равен 3?

Ниже приведен код как есть, который добавляет все ребра в список, а затем записывает список в CSV:

import csv
import networkx as nx
from networkx.algorithms import bipartite

def fold_network(input_file):

    # load text file into a dict with head as keys
    header = ['Event','Name']        
    rawData = [{key: value for (key, value) in zip(header, line.strip().split(','))} for line in open(input_file)]

    # create edgelist for Name -x- Event relationships
    edgelist = []
    for i in rawData:
        edgelist.append(
        (i['Event'],
        i['Name'])    
        )

    # create a unique list of Name and Event for nodes
    Event = sorted(set([i['Event'] for i in rawData]))
    Name = sorted(set([i['Name'] for i in rawData]))

    # add nodes and edges to a graph
    B = nx.Graph()
    B.add_nodes_from(Event, bipartite=0)
    B.add_nodes_from(Name, bipartite=1)
    B.add_edges_from(edgelist)

    # create bipartite projection graph
    name_nodes, event_nodes = bipartite.sets(B)
    event_nodes = set(n for n,d in B.nodes(data=True) if d['bipartite']==0)
    name_nodes = set(B) - event_nodes

    # project graph and write projected graph's edgelist to a list
    seen = set()
    folded = []
    for u in name_nodes:
    #    seen=set([u]) # print both u-v, and v-u
        seen.add(u) # don't print v-u
        unbrs = set(B[u])
        nbrs2 = set((n for nbr in unbrs for n in B[nbr])) - seen
        for v in nbrs2:
            vnbrs = set(B[v])
            common = unbrs & vnbrs
            weight = len(common)
            row = u, v, weight
            folded.append(row)

    # write folded list containing only edges with weight greater than or equal to 3 to CSV
    for i in folded:
        if i[2] >= 3:
            with open('outfile.csv', 'wb') as f:
                csv.writer(f).writerows(i)

person CurtLH    schedule 21.08.2014    source источник
comment
Итак, почему бы вам просто не заменить folded.append(row) вызовом, который записывает строку в файл? Если csv.writer не поддерживает его, все, что вам нужно, это открыть файл и дополнить его.   -  person Tymoteusz Paul    schedule 21.08.2014
comment
@Puciek - я думаю, что это отличная идея, но, к сожалению, я не смог понять, как заставить это работать правильно.   -  person CurtLH    schedule 21.08.2014
comment
Что ты имеешь в виду? Что вы пробовали и почему это не сработало?   -  person Tymoteusz Paul    schedule 21.08.2014


Ответы (1)


Что ж, ответ на главный вопрос (есть веская причина, по которой вы должны ограничить свой вопрос, скажем, одним вопросом) довольно прост — все, что вам нужно, это переделать этот крошечный фрагмент кода:

    for v in nbrs2:
        vnbrs = set(B[v])
        common = unbrs & vnbrs
        weight = len(common)
        row = u, v, weight
        folded.append(row)

Во что-то вроде:

    for v in nbrs2:
        vnbrs = set(B[v])
        common = unbrs & vnbrs
        weight = len(common)
        row = u, v, weight
        f = open('outfile.csv', 'a')
        f.write(row)
        f.close()

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

person Tymoteusz Paul    schedule 21.08.2014
comment
Спасибо, но я получаю ошибку TypeError: expected a character buffer object. Я вижу, это потому, что write требует строки или буфера. - person CurtLH; 21.08.2014
comment
Как я уже сказал, вам, скорее всего, придется отформатировать строку (среди прочего). Если у вас есть конкретные вопросы о том, как это сделать (включая то, что вы пробовали и в чем ваша проблема), не стесняйтесь спрашивать в комментариях. Но если вы ищете полное решение, которое вы можете просто скопировать/вставить в свой код без каких-либо усилий с вашей стороны, что ж, возможно, кто-то еще придет достаточно скоро и сделает это за голосование. - person Tymoteusz Paul; 21.08.2014
comment
Я очень новичок в python, но я пробовал row = ','.join([u, v, str(weight)]), но это, видимо, записывает все в первую строку. - person CurtLH; 21.08.2014
comment
Это не проблема новичка в python, скорее проблема нежелания выполнять работу (так же, как вы проигнорировали мой первоначальный комментарий о том, что это не сработало в первую очередь). Чтобы решить эту проблему, вам нужно разбить ее на цены и посмотреть, что работает не так, как предполагалось, поэтому логичным шагом будет распечатать ROW как есть (просто добавьте print(row) в свой код), тогда, если это хорошо - добавьте дополнительную печать после того, как попытаетесь отформатировать ее, и посмотрите, нормально ли это работает. Есть также инструменты, которые делают это намного проще, например, PDB — docs.python.org /3/библиотека/pdb.html - person Tymoteusz Paul; 21.08.2014