2016-11-07 1 views
3

저는 약 2 개월 동안 Python으로 작업 해 왔기 때문에 잘 이해하고 있습니다.CSV 파일에서 행렬 만들기

제 목표는 CSV 데이터를 사용하여 매트릭스를 만든 다음 해당 CSV 파일의 세 번째 열에있는 데이터에서 매트릭스를 채우는 것입니다.

내가 지금까지이 코드를 내놓았다 :

import csv 

import csv 
def readcsv(csvfile_name): 
     with open(csvfile_name) as csvfile: 
     file=csv.reader(csvfile, delimiter=",") 

#remove rubbish data in first few rows 

     skiprows = int(input('Number of rows to skip? ')) 
      for i in range(skiprows): 
       _ = next(file) 

#change strings into integers/floats 

      for z in file: 
       z[:2]=map(int, z[:2]) 
       z[2:]=map(float, z[2:]) 
       print(z[:2]) 
     return 

을 위의 코드와 함께 쓰레기 데이터를 제거한 후, CSV 파일의 데이터는 다음과 같습니다

Input: 
    1 1 51 9 3 
    1 2 39 4 4 
    1 3 40 3 9 
    1 4 60 2 . 
    1 5 80 2 . 
    2 1 40 6 . 
    2 2 28 4 . 
    2 3 40 2 . 
    2 4 39 3 . 
    3 1 10 . . 
    3 2 20 . . 
    3 3 30 . . 
    3 4 40 . . 
    . . . . . 

출력은해야 모양은 다음과 같습니다.

 1 2 3 4 . . 
    1 51 39 40 60 
    2 40 28 40 39 
    3 10 20 30 40 
    . 
    . 

이 CSV 파일에는 약 1,000 개의 행과 열이 있습니다. CSV 파일의 처음 3 열만 관심이 있습니다. 따라서 첫 번째와 두 번째 열은 기본적으로 행렬에 대한 좌표와 유사하며 세 번째 열에 데이터로 행렬을 채 웁니다.

많은 시행 착오 끝에, 나는 멍청이가 행렬로가는 길임을 깨달았다. 이것은 내가 예를 들어 데이터로 지금까지 뭘하려 : 나를 행렬을 생성하기 위해 내 스크립트에 내 모든 데이터를 지정하는

left_column = [1, 2, 1, 2, 1, 2, 1, 2] 
    middle_column = [1, 1, 3, 3, 2, 2, 4, 4] 
    right_column = [1., 5., 3., 7., 2., 6., 4., 8.] 

    import numpy as np 
    m = np.zeros((max(left_column), max(middle_column)), dtype=np.float) 
    for x, y, z in zip(left_column, middle_column, right_column): 
     x -= 1 # Because the indicies are 1-based 
     y -= 1 # Need to be 0-based 
     m[x, y] = z 
    print(m) 

    #: array([[ 1., 2., 3., 4.], 
    #:  [ 5., 6., 7., 8.]]) 

그러나, 그것은 비현실적이다. 생성기를 사용하여 CSV 파일에서 데이터를 가져 왔지만 제대로 작동하지 않았습니다.

나는 그것이 할 수있는만큼 많은 numpy를 배웠지 만, 내 데이터가 이미 매트릭스 형태로 있어야하는 것처럼 보입니다. 그렇지 않습니다.

+0

마지막 두 열의 의미를 이해하지 못합니다. 처음 세 개는 분명합니다 ... (행, 열, 값) – Nikaidoh

답변

1

이 내 솔루션은 사용 :

l, c, v = np.loadtxt('test.txt', skiprows=1).T 
m = coo_matrix((v, (l-1, c-1)), shape=(l.max(), c.max())) 

그런 다음 당신이 coo_matrixnp.ndarray A를 변환 할 수 있습니다 csv 라이브러리 및 csv의 index \ position 작업 (사용 나는 현재 행에 메모리를 mantain하는 데 사용되는 오프셋)

import csv 

with open('test.csv', 'r') as csvfile: 
    spamreader = csv.reader(csvfile, delimiter=',') 
    list_of_list = [] 
    j=0 
    lines = [line for line in spamreader] 
    for i in range(len(lines)): 
     list_ = [] 
     if(len(lines)<=i+j): 
      break; 
     first = lines[i+j][0] 
     while(first == lines[i+j][0]): 
      list_.append(lines[i+j][2]) 
      j+=1 
      if(len(lines)<=i+j): 
       break; 
     j-=1 
     list_of_list.append(list(map(float,list_))) 

maxlen = len(max(list_of_list)) 
print("\t"+"\t".join([str(el) for el in range(1,maxlen+1)])+"\n") 
for i in range(len(list_of_list)): 
    print(str(i+1)+"\t"+"\t".join([str(el) for el in list_of_list[i]])+"\n") 

어쨌든 Saullo에 의해 게시 된 솔루션이 더 우아한

이 내 출력 : 내가 쓴

 1  2  3  4  5 

1  51.0 39.0 40.0 60.0 80.0 

2  40.0 28.0 40.0 39.0 

3  10.0 20.0 30.0 40.0 

csv가 너무 커서 메모리에 넣을 수없는 새로운 버전의 코드.

import csv 

with open('test.csv', 'r') as csvfile: 
    spamreader = csv.reader(csvfile, delimiter=',') 
    list_of_list = [] 

    line1 = next(spamreader) 
    first = line1[0] 
    list_ = [line1[2]] 
    for line in spamreader: 
     while(line[0] == first): 
      list_.append(line[2]) 
      try: 
       line = next(spamreader) 
      except : 
       break; 
     list_of_list.append(list(map(float,list_))) 
     list_ = [line[2]] 
     first = line[0] 

maxlen = len(max(list_of_list)) 
print("\t"+"\t".join([str(el) for el in range(1,maxlen+1)])+"\n") 
for i in range(len(list_of_list)): 
    print(str(i+1)+"\t"+"\t".join([str(el) for el in list_of_list[i]])+"\n") 

어쨌든 아마도 데이터가 2 차원 배열에 들어 가지 않을 수도 있기 때문에 매트릭스에서 작업해야합니다 (및 스왑 작업).

+0

안녕하세요, 코드를 실행하려했는데 7 번 줄에 'MemoryError'오류가있었습니다. 이견있는 사람? – dizzyLife

+0

이전에 게시 한 csv 또는 다른 csv를 입력으로 사용 했습니까? 더 큰 것, 아마도? 더 큰 예제에서 테스트하지 않았습니다 – Nikaidoh

+0

아마도 CSV가 너무 커서 메모리에 들어가기에 너무 커서 반복기를 사용해야합니다. – Nikaidoh

3

scipy.sparse.coo_matrix을 사용하면이 데이터를 매우 편리하게로드 할 수 있습니다.

사용자의 입력 작업 :

Input: 
    1 1 51 9 3 
    1 2 39 4 4 
    1 3 40 3 9 
    1 4 60 2 . 
    1 5 80 2 . 
    2 1 40 6 . 
    2 2 28 4 . 
    2 3 40 2 . 
    2 4 39 3 . 
    3 1 10 . . 
    3 2 20 . . 
    3 3 30 . . 
    3 4 40 . . 
    . . . . . 

당신은 할 수 :

In [9]: m.toarray() 
Out[9]: 
array([[ 51., 39., 40., 60., 80.], 
     [ 40., 28., 40., 39., 0.], 
     [ 10., 20., 30., 40., 0.]]) 
+0

안녕하세요. 첫 번째 도움에 감사드립니다. file.csv라는 csv 파일로 test.txt를 대체하여 코드를 실행하려고 시도했지만 오류가 발생했습니다. IDLE의 하위 프로세스가 연결을 만들지 않았습니다. IDLE은 하위 프로세스를 시작할 수 없거나 개인용 소프트웨어가 연결을 차단하고 있습니다. 이 메모는 메모장에 모든 데이터를 저장해야합니까? – dizzyLife

+0

@dizzy 확실하지만, 유효한 데이터 만 보관했는지 확인하십시오.이 경우에는 세 번째 열까지만 보관해야합니다. 그렇지 않으면 'l, c, v = np.loadtxt ("file.csv ", skiprows = 1) .T [: 3, :]'세 번째 열까지 읽기를 제한하려면 –

+0

@dizzyLife 또한'csv' 파일의 구분 기호가 다른지 확인하십시오 공백에서. 그렇다면'delimiter = ","'를'loadtxt' 함수 (또는 거기에있는 다른 구분 문자)에 건네 야합니다. –

2

pandas을 심각하게 고려해야합니다. 이런 종류의 일에 정말로 이상적입니다. 나는 당신의 데이터가 없기 때문에 나는 당신에게 실제적인 솔루션을 제공 할 수는 없지만 나는 다음과 같은 것을 시도 할 것이다 :

import pandas as pd 
df = pd.read_csv('test.csv', usecols=[0,1,2], names=['A', 'B', 'C']) 
pd.pivot_table(df, index='A', columns='B', values='C') 

두 번째 줄은 팬더 DataFrame 객체로 데이터를 가져옵니다 (로 이름을 변경을 응용 프로그램에 더 유용한 기능). 피벗 테이블은 찾고있는 행렬을 만들고 누락 된 데이터를 정상적으로 처리합니다.

+0

주석 주셔서 감사합니다. CSV 파일을 보낸다면 도움이 될까요? 나는 많은 시도 후에 그것을 작동시키지 못했습니다. 오류 : AttributeError : '모듈'객체에 'read_csv'속성이 없습니다. – dizzyLife

+0

@dizzyLife : 어떤 팬더 버전을 사용하고 있습니까? 판다를 pd로 가져온 경우, "pd .__ version__"을 파이썬에 입력하십시오. 나는 판다 0.18.0을 사용하고 있습니다. 그래서 아마도 당신은 더 새로운 팬더 버전이 필요합니까? –

+0

@dizzyLife : 이전 댓글을 무시하고, read_csv는 처음부터 팬더에있었습니다. 귀하의 실수는 아마 판다가 올바르게 설치되지 않았 음을 의미합니다. "pdf로 가져 오기"실행시 예외가 발생 했습니까? –