2016-03-17 53 views
0

這裏是我的test_data.csv:蟒蛇 - numpy的:讀CSV與正確的值類型numpy的

A,1,2,3,4,5 
B,6,7,8,9,10 
C,11,12,13,14,15 
A,16,17,18,19,20 

,我使用下面的代碼讀給一個numpy的數組:

def readCSVToNumpyArray(dataset): 
    with open(dataset) as f: 
     values = [i for i in csv.reader(f)] 

    data = numpy.array(values) 

    return data 

在主代碼,我有:

numpyArray = readCSVToNumpyArray('test_data.csv') 
    print(numpyArray) 

這使我的輸出:

(array([['A', '1', '2', '3', '4', '5'], 
     ['B', '6', '7', '8', '9', '10'], 
     ['C', '11', '12', '13', '14', '15'], 
     ['A', '16', '17', '18', '19', '20']], 
     dtype='|S2')) 

但是,所有的數字數組中被視爲string,有沒有讓他們存儲爲float不通過每個元素去並指定類型的好辦法?

謝謝!

+0

'numpy.ndarrays'是同質的。這是他們改進性能的原因之一。也許你可以有兩個單獨的數組,一個用於數字,另一個用於字符串?或者是一個字符串和數組數組的列表?否則,您需要查看[numpy records](http://docs.scipy.org/doc/numpy-dev/reference/generated/numpy.core.records.fromfile.html)或其他一些數據結構。你有沒有考慮過熊貓數據框? –

+0

看一看[pandas](http://pandas.pydata.org/pandas-docs/stable/io.html#io-read-csv-table),它非常適合加載csv。你可以通過'asarray(table)'方便地將pandas表('DataFrame'實際)轉換爲numpy數組。 –

+0

如果你不想涉及一個額外的包(熊貓),請注意,'np.fromfile'或'np.genfromtxt'也是閱讀文本文件的好工具,在你的情況下你必須定義一個數據類型並且通過它對這些功能。去看看他們的文檔字符串,並看看'np.dtype'。 –

回答

1

由於每行的第一個字符是一個字符串,所以你必須在numpy中使用一個更靈活的類型,叫做「object」。使用此功能嘗試,看看如果這是你在找什麼:

def readCSVToNumpyArray(dataset): 
     values = [[]] 
     with open(dataset) as f: 
      counter = 0 
      for i in csv.reader(f): 
       for j in i: 
        try: 
         values[counter].append(float(j)) 
        except ValueError: 
         values[counter].append(j) 
       counter = counter + 1 
       values.append([]) 

     data = numpy.array(values[:-1],dtype='object') 

     return data 

    numpyArray = readCSVToNumpyArray('test_data.csv') 
    print(numpyArray) 

的結果是:

[['A' 1.0 2.0 3.0 4.0 5.0] 
    ['B' 6.0 7.0 8.0 9.0 10.0] 
    ['C' 11.0 12.0 13.0 14.0 15.0] 
    ['A' 16.0 17.0 18.0 19.0 20.0]] 
0

np.genfromtxt可以方便地將數據加載到一個結構數組。這將是一個一維數組,爲每列一個字段:

模擬文件與行的列表:

In [265]: txt=b"""A,1,2,3,4,5 
     .....: B,6,7,8,9,10 
     .....: C,11,12,13,14,15 
     .....: A,16,17,18,19,20""" 
    In [266]: txt=txt.splitlines() 
    In [267]: A=np.genfromtxt(txt,delimiter=',',names=None,dtype=None) 
    In [268]: A 
    Out[268]: 
    array([(b'A', 1, 2, 3, 4, 5), (b'B', 6, 7, 8, 9, 10), 
      (b'C', 11, 12, 13, 14, 15), (b'A', 16, 17, 18, 19, 20)], 
      dtype=[('f0', 'S1'), ('f1', '<i4'), ('f2', '<i4'), ('f3', '<i4'), ('f4', '<i4'), ('f5', '<i4')]) 

它推斷出來自列值dtype - 串和整數。字段由名稱

In [269]: A['f0'] 
Out[269]: 
array([b'A', b'B', b'C', b'A'], 
     dtype='|S1') 
In [270]: A['f1'] 
Out[270]: array([ 1, 6, 11, 16]) 

訪問我還可以定義一個dtype那將投入串在一個領域,其他領域的所有其他值。

In [271]: A=np.genfromtxt(txt,delimiter=',',names=None,dtype='S2,(5)int') 
In [272]: A 
Out[272]: 
array([(b'A', [1, 2, 3, 4, 5]), (b'B', [6, 7, 8, 9, 10]), 
     (b'C', [11, 12, 13, 14, 15]), (b'A', [16, 17, 18, 19, 20])], 
     dtype=[('f0', 'S2'), ('f1', '<i4', (5,))]) 
In [273]: A['f1'] 
Out[273]: 
array([[ 1, 2, 3, 4, 5], 
     [ 6, 7, 8, 9, 10], 
     [11, 12, 13, 14, 15], 
     [16, 17, 18, 19, 20]]) 
1

我會在使用熊貓閱讀它,它可以讓你很容易地設置每列的dtype。

import numpy as np 
import pandas as pd 

pdDF = pd.read_csv(
    'test_data.csv', 
    header=None, 
    names=list('abcdef'), 
    dtype=dict(zip(list('abcdef'),[str]+[float]*5))) 

現在每列都會有適當的dtype。

pdDF.b 
Out[24]: 
0  1 
1  6 
2 11 
3 16 
Name: b, dtype: float64 

如果你仍然希望它在numpy數組中,你可以只取值。

npArr = pdDF.values 

npArr 
Out[27]: 
array([['A', 1.0, 2.0, 3.0, 4.0, 5.0], 
     ['B', 6.0, 7.0, 8.0, 9.0, 10.0], 
     ['C', 11.0, 12.0, 13.0, 14.0, 15.0], 
     ['A', 16.0, 17.0, 18.0, 19.0, 20.0]], dtype=object) 

它仍然將是對「行」數組的對象,因爲你不能讓「A」變成浮動,但可根據需要單獨的值將是浮動。

type(npArr[0,1]) 
Out[28]: float 

最後,如果你只想float數組,這也是很容易...只是吐出所有,但第一列作爲一個數組,這將有D型:浮動,而不是對象。

pdDF.loc[:,pdDF.columns>='b'].values 
Out[28]: 
array([[ 1., 2., 3., 4., 5.], 
     [ 6., 7., 8., 9., 10.], 
     [ 11., 12., 13., 14., 15.], 
     [ 16., 17., 18., 19., 20.]]) 

pdDF.loc[:,pdDF.columns>='b'].values.dtype 
Out[29]: dtype('float64')