2013-05-23 2 views
1

기존 .txt 파일에 새로운 데이터 열을 추가하는 방법은 무엇입니까? 기본적으로 저는 5 개의 사전을 생성하고 있습니다. 생성 할 때마다 새 열의 마스터 텍스트 파일에 값을 쓰고 싶습니다. 나는 프로그램이 모든 사전을위한 새 열을 시작했다 어떻게 지금Python을 사용하여 열 단위로 .txt 파일에 쓰기

# Import personal module 
import graphGenerator as gg 
# Open file for writing data to 
case=open(r'J:\FOIL\mediansandmeans.txt','w') 
# Run code 
for i in range(5): 
    # create a graph using NetworkX and a code I wrote to read in an edgelist from a txt file 
    G=gg.graph_creator(i+1) 
    # calculate degree of all nodes using NetworkX--returns a dictionary 
    d=nx.degree(G,weighted=True) 
    # print dictionary values to text file 
    for j in d.keys(): 
     case.write('%s\n' % d[j]) 

: 나는 내가 쓴 다른 프로그램을 호출하기 때문에 당신이 그것을 실행할 수 없습니다 비록 내 코드를 표시 할 수 있습니다?

+0

여러분이 가지고있는 이상한 들여 쓰기입니다. –

+0

파이썬은 공백 문자이므로 들여 쓰기를 확인하십시오. – thegrinner

+0

왜이 용도로 데이터베이스를 사용하지 않습니까? 파일을 고수하고 싶다면 어떤 종류의 데이터에 따라 ['pandas'] (http://pandas.pydata.org/) 또는''numpy' (http://www.numpy.org/)를 사용하십시오 너는 상대하고있다. 그렇지 않으면 전체 파일을 읽고 열을 추가 한 다음 파일을 다시 써야합니다. –

답변

0

텍스트 파일에 새 열을 추가하는 것은 비효율적입니다. 전체 파일을 들여다 보거나, 열을 추가하고, 기존 파일을 덮어 쓰거나, 데이터베이스 또는 XML 파일과 같은 기본 개념의 열이있는 것을 사용하십시오.

5

텍스트 파일은 순차적으로 저장됩니다. 라인 1은 끝나는 라인 2가 시작됩니다. 중간에 머티리얼을 수정하고 하나의 문자를 추가하거나 하나만 삭제하려면 뒤 따르는 모든 것을 읽고 파일의 새 오프셋에서 다시 써야합니다. 즉, 전체 파일을 읽고 쓰거나, 다른 저장소 모델 (예 : 데이터베이스)을 사용하는 것이 좋습니다.

정말 파일에 정보를 추가했다 당신이 열 현명한, 당신은 고정 길이의 라인을 작성 에 의해 그것을 할 수 있다면, 공백 패딩; 그런 다음 파일을 검색하여 일부 공간을 새 데이터로 덮어 씁니다. 나는 끔찍한 접근법이기 때문에 코드를 제공하지 않을 것이다. 고정 길이 레코드는 1970 년대에 나왔다. 그리고 저는 그것이 귀하의 경우에 필요하거나 적절하다고 생각하지 않습니다.

코드를 보면 파일에 열을 추가 할 필요가 없다고 생각합니다. 최선의 해결책은 실제로 2 차원 배열의 값을 수집하는 것이므로 생각을 끝내면 원하는 형식으로 한꺼번에 쓸 수 있습니다. 기가 바이트 상당의 포인트가 없으면 한 번에 하나의 열을 쓸 이유가 없습니다.

편집 : 당신이 배열 아이디어를 좋아하기 때문에는 여기를 생성하고 쉽게을 작성하는 방법은 다음과 같습니다

from collections import defaultdict 
degrees = defaultdict(list) 

for i in range(5): 
    G=gg.graph_creator(i+1) 
    d=nx.degree(G,weighted=True) 
    for j in d.keys(): 
     degrees[j].append(d[j]) 

for k in sorted(degrees.keys()): 
    case.write("%s: %s\n" % (k, "\t".join(degrees[k]))) 

은 "두 차원 배열"로 유지, 실제로 목록의 사전 당신의 번역. (반환 된 모든 사전은 정확히 동일한 키를 가지고 있습니다.) 코드는 두 가지 편리한 파이썬 기능을 사용합니다. defaultdict 클래스는 첫 번째 열을 기록 할 때 명시 적으로 각 배열 행을 만드는 번거 로움을 줄여줍니다. 그리고 출력 코드는 5 개의 값을 하나의 탭으로 구분 된 문자열로 결합하여 출력합니다.

사전의 키를 정렬하지 않으면 임의의 순서로 가져올 수 있습니다. 일반적으로 출력 할 때 원하는 것은 아닙니다.

+0

정말 고마워, 나는 2 차원 어레이를 생각하지 않았다. – user2414615

+0

+1. 그러나 키가 이미 정렬되었거나 일관된 방식으로 정렬 된 경우에는 'OrderedDict'를 사용하여 수동 정렬을 건너 뛸 수 있습니다. (dict 명령을 내리고 동시에 기본값을 설정하는 데 필요한 트릭이 있지만 stdlib 설명서에 설명되어 있습니다.) – abarnert

+0

감사합니다. @abarnert, 좋은 제안입니다. 그러나'nx degrees()'가 작동하려면'OrderedDict'를 반환해야합니다. 어쨌든 코드를 사용하여 가능한 다른 세분화가 있습니다 (예 : 반복 할 때'.keys()'를 명시 적으로 언급 할 필요가 없음). 나는 OP가 전문 프로그래머가 아니므로 분명하고 간단하게 유지했다. – alexis

0

난 당신이/정말 그렇게 같은 ' ' 구분으로 CSV를, 열이 파일을 사용하게하려는해야하는 경우가 있지만 비효율적 동의 : 각 행에 대한 목록을 작성하는 경우, 예를 들어

및 다음 칼럼에 대해 원하는 각 값을 추가, 당신은 지금처럼 쓸 수 있습니다 :

import csv 
with open('J:\FOIL\mediansandmeans.csv', 'wb') as case: 
    writer = csv.writer(case, delimiter=' ', 
          quotechar='"', quoting=csv.QUOTE_MINIMAL) 
    writer.writerow(['your', 'first list', 'of rows']) 
    writer.writerow(['your', 'second list', 'of rows']) 

당신은 csv documentation

에서 자세한 내용을보실 수 있습니다하지만 실제로는 이런 종류의 물건에 대한 데이터베이스를 사용한다. sqlite3을 보셨습니까?

+0

고마워! 위에서 언급했듯이 불행히도 저는 정부 컴퓨터를 사용하고 있기 때문에 설치를 승인 한 후 수행하고 잘하면 알리도록 헬프 데스크를 얻는 동안 몇 주 후에도 다른 라이브러리를 설치할 수 없습니다. 파이썬 만 가지고 있습니다. – user2414615

+2

@ user2414615 :'csv' 라이브러리는 stdlib에 내장되어 있으므로 이미 가지고 있습니다. 'sqlite3'와 동일합니다. kisamoto의 대답에있는 문서 링크를 클릭하면 python.org 사이트로 바로 이동하여이를 분명하게합니다. – abarnert

+0

감사합니다. @abarnert - 저를 때려주세요. 예 [sqlite3] (http://docs.python.org/2/library/sqlite3.html)과 [csv] (http://docs.python.org/2/library/csv.html) 모두에 있습니다. Python> 2.5 표준 라이브러리. 파이썬이'import csv, sqlite3'을 설치했다면 – Ewan

1

알렉스가 설명 하듯이 텍스트 파일은 무작위로 액세스하거나 수정할 수 없습니다. 새 데이터를 텍스트 파일의 중간에 삽입하려면 완전히 새로운 파일을 작성해야합니다.

하지만 실제로 문제가 있습니까? 당신은 단지 5 번만하고 있습니다. 현대 컴퓨터는 엄청난 양의 순차적 데이터를 하드 드라이브에 스팸으로 보내고 무작위로 검색하고 쓰는 것이 좋지 않기 때문에 낭비되는 시간은 그다지 크지 않을 수 있습니다. 그리고 이것은 간단합니다. 예 :

bakpath = path+'.bak' 
os.rename(path, bakpath) 
with open(path, 'rb') as infile, open(bakpath, 'wb') as outfile: 
    writer = csv.writer(outfile) 
    for row, newvalue in zip(csv.reader(infile), newvalues): 
     row.append(newvalue) 
     writer.writerow(row) 

만약 그렇다면 몇 가지 개선 방법이 있습니다.


대부분 분명, 당신은 데이터베이스 (같은 sqlite3) 또는 테이블 시스템 (같은 pandas 또는 pytables) 대신 CSV 파일을 사용할 수 있습니다. 이미 작성되고 사용하기 쉽고, 당신이 생각하는 것보다 더 잘 최적화 될 것입니다.


또는 각 열에 대해 별도의 파일을 사용하십시오. closing_all은 다음 stdlib에 내장되지 않도록

with closing_all([open(path, 'rb') for path in paths]) as files): 
    for row in zip(*files): 
     # each row is a tuple of columns 

,하지만 당신은 하찮게을 작성할 수 있습니다 : 그들은 하나 개의 파일만큼이나 당신은 여전히 ​​다음과 같이 액세스 할 수 있습니다 당신이 필요로하는 경우

@contextmanager 
def closing_all(things): 
    try: 
     yield things 
    finally: 
     for thing in things: 
      thing.close() 

마지막에 모든 파일을 하나의 파일로 병합하는 것은 간단합니다. 즉 N 시간 대신에 전체를 한 번 다시 작성한다는 의미입니다.


직접 임의 파일을 만들 수도 있습니다. 당신이 사전에 알고 있지만하지 경우 대략 추정

COLUMN_LENGTHS = 20, 15, 41, 12, 19 
COLUMN_STARTS = [0] + list(itertools.accumulate(COLUMN_LENGTHS)) 
ROW_LENGTH = COLUMN_STARTS[-1] + 1 

def read_cell(f, row, column): 
    f.seek(row * ROW_LENGTH + COLUMN_STARTS[column]) 
    return f.read(COLUMN_LENGTHS[column]).rstrip() 

def write_cell(f, row, column, value): 
    f.seek(row * ROW_LENGTH + COLUMN_STARTS[column]) 
    padded = value.ljust(COLUMN_LENGTHS[column]) 
    f.write(padded) 

수, 당신은 항상 할 수 있습니다 사전에 열 최대 열 길이와 번호를 알고 있다면, 당신은 공백 각 열은 단지 패드를 수 list과 유사한 클래스가 사용하는 동일한 트릭을 사용하십시오. 과대 평가. 쓴 것으로 밝혀지면, 기존의 것을 상수로 복사하여 새로 확장 된 버전으로 복사하십시오. 즉, N 번 대신 N 번만 파일 로그를 다시 쓰는 것입니다.


또 다른 대안은 파일을 전치 형식으로 유지하는 것입니다. 따라서 새로운 열 대신 새로운 행을 추가하는 것입니다. 그냥 'a' 모드에서 파일을 열고 쓰기 만하면됩니다.

필요하다면 언제든지 다시 끝낼 수 있습니다. 즉, N 번 대신 파일을 한 번 다시 작성합니다.

+0

감사합니다. 실제로이 코드를 133 번 사용하려고합니다. ;) 그리고 유감스럽게도 저는 정부 컴퓨터로 일하고 있습니다. 따라서 설치를 승인 한 다음 그것을 수행하고 올바르게 작동하도록 헬프 데스크를 얻는 동안 몇 주 동안 지체없이 다른 어떤 라이브러리도 설치할 수 없습니다. 파이썬 만 가지고 있습니다. – user2414615

+0

@ user2414615 :'csv','os','contextlib','sqlite3','itertools'는 제가 언급 한 거의 모든 것이 "기본적인 파이썬"의 일부입니다. 파이썬과 함께 제공되는 표준 라이브러리를 사용하지 않는다면 파이썬을 사용하지 않을 것입니다. 그것이 "배터리가 포함 된"것이 전부입니다. – abarnert

+0

모든 도움에 감사드립니다! 나는 이들 중 일부 (sqlite3 및 contextlib)를 인식하지 못했습니다. 나는 그들에 대해 더 연구 할 것이다. – user2414615