2016-02-03 59 views
0

我想從SQL(使用pyodbc)讀取一些數據到一個numpy結構數組(我相信結構化數組是由於多個dtypes)。閱讀數據到結構化數組與多個dtypes

import pyodbc 
import numpy as np 
cnxn = pyodbc.connect('DRIVER={SQL Server};Server=SERVER;Database=DB;Trusted_Connection=Yes;') 
cursor = cnxn.cursor() 
sql_ps = "select a, b from table" 
cursor.execute(sql_positions) 
p_data = cursor.fetchall() 
cnxn.close 

ndtype = np.dtype([('f1','>f8'),('f2','|S22')]) 
p_data = np.asarray(p_data, dtype=ndtype) 

然而,這將返回:

TypeError: expected a readable buffer object 

如果我加載到陣列作爲元組

p_data_tuple = np.asarray([tuple(i) for i in p_data], dtype=ndtype) 

它的工作原理,但是p_data_tuple是元組的陣列,而不是一個二維數組,意思是我不能調用使用的元素p_data_tuple[0,1]

是否有任何我知道如何將數據直接返回到具有多個dtypes的str數組中,或者將元組數組轉換成多個dtypes的二維數組或其他解決方案?

感謝

+0

如果通過pandas運行查詢會發生什麼情況:'df = pd.read_sql_query(sql_ps,cnxn)' – Colin

+0

我可以採用該方法,然後使用'p_data_2 = df.asmatrix(['a' ,'b'])'但似乎沒有讓我指定dtype,而'p_data_2'將是'object'。 – pj87

+0

*「它可行,但是p_data_tuple是一個元組數組,與2d數組相反,這意味着我無法使用p_data_tuple [0,1]調用元素」*這就是您在創建結構化數組時所發生的情況。它將是一個*一維*結構數組。如果結構中字段的數據類型不完全相同,那麼*不能*以二維數組的形式訪問它。 –

回答

0

cursor.fetchall回報的記錄列表。記錄是'行對象與元組相似,但它們也允許按名稱訪問列'(http://mkleehammer.github.io/pyodbc/)。聽起來像是我的一個點名,儘管課程細節可能會有所不同。

sql_ps = "select a, b from table" 
cursor.execute(sql_positions) 
p_data = cursor.fetchall() 
cnxn.close 

只是爲了好玩,讓我們改變了dtype使用相同的字段名稱爲sql

ndtype = np.dtype([('a','>f8'),('b','|S22')]) 

這是不行的,大概是因爲tuple-like記錄是不是一個真正的元組。

p_data = np.array(p_data, dtype=ndtype) 

因此,我們將每條記錄轉換爲一個元組。結構化數組將他們的數據作爲元組列表。

p_data = np.array([tuple(i) for i in p_data], dtype=ndtype) 

現在,您可以通過現場或通過

p_data['a'] # 1d array of floats 
p_data['b'][1] # one string 
p_data[10] # one record 

的記錄從p_data顯示訪問數據的元組,儘管它實際上有一個像dtype父陣列。

結構化陣列上有一個變種,recarray,它增加了按屬性名稱訪問字段的能力,例如, p_rec.a。這更接近dp光標記錄,但不會增加很多。

所以這個結構化數組非常類似於你的源sql表 - 有字段和行。它不是2d數組,但按字段名稱進行索引類似於按列號索引2d數組。

pandas做了類似的事情,雖然它經常使用dtype=object(就像Python列表的指針)。它跟蹤「行」標籤。