PYODBC до Pandas - DataFrame не работает - Форма переданных значений (x, y), индексы подразумевают (w, z)
Раньше я использовал pyodbc с python, но теперь я установил его на новую машину (выиграл 8 64 бит, Python 2.7 64 бит, PythonXY со Spyder).
До того, как я привык (внизу вы можете найти более реальные примеры):
columns = [column[0] for column in cursor.description]
temp = cursor.fetchall()
data = pandas.DataFrame(temp,columns=columns)
и все будет хорошо. Теперь кажется, что DataFrame больше не может преобразовать из данных, полученных из курсора. Он возвращает:
Форма прошедших значений равна (x, y), из индексов следует (w, z)
Я вижу, где проблема. В принципе, представьте, что я беру только одну строку. Затем DataFrame хотел бы сформировать его (1,1), только один элемент. Хотя я хотел бы иметь (1, X), где X - длина списка.
Я не уверен, почему поведение изменилось. Возможно, это версия Pandas у меня есть, или pyobbc, но обновление проблематично. Я попытался обновить некоторые модули, но он завинчивает все, любой метод, который я использую (двоичные файлы - для правильной машины/установки - pip install, easy-install, что-нибудь! И т.д., Что очень расстраивает. Выиграйте 8 бит с этого момента для Python).
Реальные примеры:
sql = 'Select * form TABLE'
cursor.execute(sql)
columns = [column[0] for column in cursor.description]
data = cursor.fetchall()
con.close()
results = DataFrame(data, columns=columns)
Возвращает:
* ValueError: Форма переданных значений (1, 1540), индексы подразумевают (51, 1540)
Обратите внимание:
ipdb> type(data)
<type 'list'>
ipdb> np.shape(data)
(1540, 51)
ipdb> type(data[0])
<type 'pyodbc.Row'>
Теперь, например, если мы делаем:
ipdb> DataFrame([1,2,3],columns=['a','b','c'])
* ValueError: Форма переданных значений (1, 3), индексы подразумевают (3, 3)
и если мы это сделаем:
ipdb> DataFrame([[1,2,3]],columns=['a','b','c'])
a b c
0 1 2 3
Однако даже пытается:
ipdb> DataFrame([data[0]], columns=columns)
*** ValueError: Shape of passed values is (1, 1), indices imply (51, 1)
или
ipdb> DataFrame(data[0], columns=columns)
*** PandasError: DataFrame constructor not properly called!
Пожалуйста, помогите:) Спасибо!
Ответы
Ответ 1
По состоянию на Pandas 0.12 (я считаю) вы можете сделать:
import pandas
import pyodbc
sql = 'select * from table'
cnn = pyodbc.connect(...)
data = pandas.read_sql(sql, cnn)
До 0.12 вы можете сделать:
import pandas
from pandas.io.sql import read_frame
import pyodbc
sql = 'select * from table'
cnn = pyodbc.connect(...)
data = read_frame(sql, cnn)
Ответ 2
Это потому, что курсор возвращает не список кортежей, а список объектов Row, которые похожи на кортежи, лучше, на самом деле, но они путают конструктор DataFrame pandas. В исходном примере сделайте это перед созданием фрейма данных:
for i in range(0,len(temp)):
temp[i]=tuple(temp[i])