2012-04-23 42 views
6

Tôi đang viết một phương thức để tạo một mảng từ tệp dữ liệu. Phương pháp này trông giống như:Loại bỏ dtype ở cuối mảng numpy

import numpy 
def readDataFile(fileName): 
    try: 
     with open(fileName, 'r') as inputs: 
      data = None 
      for line in inputs: 
       line = line.strip() 
       items = line.split('\t') 
       if data == None: 
        data = numpy.array(items[0:len(items)]) 
       else: 
        data = numpy.vstack((data, items[0:len(items)])) 
       return numpy.array(data) 
    except IOError as ioerr: 
     print 'IOError: ', ioerr 
     return None 

tập tin dữ liệu của tôi chứa dòng số, mỗi trong số đó được tách ra khỏi nhau bởi một tab, ví dụ:

1 2 3 
4 5 6 
7 8 9 

Và tôi hy vọng sẽ nhận được một mảng như sau :

array([[1, 2, 3], 
     [4, 5, 6], 
     [7, 8, 9]]) 

Tuy nhiên, kết quả chứa dtype ở phần cuối của nó:

array([[1, 2, 3], 
     [4, 5, 6], 
     [7, 8, 9]], dtype='|S9') 

Do đó, tôi không thể thực hiện một số thao tác trên kết quả, ví dụ: nếu tôi cố gắng để tìm giá trị tối đa cho mỗi dòng sử dụng result.max(0), tôi sẽ nhận được một lỗi:

TypeError: cannot perform reduce with flexible type.

Vì vậy, bất cứ ai có thể cho tôi biết những gì sai với mã của tôi và làm thế nào để sửa chữa nó? Cảm ơn rất nhiều.

Trả lời

8

Việc sửa chữa đơn giản nhất là sử dụng loadtxt NumPy của:

data = numpy.loadtxt(fileName, dtype='float') 

Just FYI, sử dụng numpy.vstack bên trong một vòng lặp là một ý tưởng tồi. Nếu bạn quyết định không sử dụng loadtxt, bạn có thể thay thế vòng lặp của mình bằng cách sau để khắc phục vấn đề dtype và loại bỏ numpy.vstack.

data = [row.split('\t') for row in inputs] 
data = np.array(data, dtype='float') 

Cập nhật

Mỗi lần vstack được gọi là nó làm cho một mảng mới và sao chép nội dung của mảng cũ sang mới. Bản sao này là khoảng O (n) trong đó n là kích thước của mảng và nếu vòng lặp của bạn chạy n lần toàn bộ điều trở thành O (n ** 2), nói cách khác là chậm. Nếu bạn biết kích thước cuối cùng của mảng trước thời hạn, tốt hơn là tạo mảng bên ngoài vòng lặp và điền vào mảng hiện có. Nếu bạn không biết kích thước cuối cùng của mảng, bạn có thể sử dụng danh sách bên trong vòng lặp và gọi vstack ở cuối. Ví dụ:

import numpy as np 
myArray = np.zeros((10,3)) 
for i in xrange(len(myArray)): 
    myArray[i] = [i, i+1, i+2] 

# or: 
myArray = [] 
for i in xrange(10): 
    myArray.append(np.array([i, i+1, i+2])) 
myArray = np.vstack(myArray) 
+1

Cảm ơn, mã của bạn hoạt động thực sự tốt. Nhưng bạn có thể làm rõ tại sao nó là một ý tưởng tồi để đưa numpy.vstack bên trong một vòng lặp? Chúc mừng. –

3

... Bạn đã thử biến chúng thành số trước?

items = [int(x) for x in line.split('\t')] 
6

Dưới đây là làm thế nào bạn thay đổi các kiểu dữ liệu trong NumPy:

>>> x 
array([[1, 2, 3], 
     [4, 5, 6], 
     [7, 8, 9]]) 
>>> x.astype('|S9') 
array([['1', '2', '3'], 
     ['4', '5', '6'], 
     ['7', '8', '9']], 
     dtype='|S9') 
>>> x.astype('Float64') 
array([[ 1., 2., 3.], 
     [ 4., 5., 6.], 
     [ 7., 8., 9.]]) 
>>> x.astype('int') 
array([[1, 2, 3], 
     [4, 5, 6], 
     [7, 8, 9]]) 
Các vấn đề liên quan