PYODBC 到 Pandas - DataFrame 不起作用 - 传递值的形状是(x,y),索引暗示(w,z)
Posted
技术标签:
【中文标题】PYODBC 到 Pandas - DataFrame 不起作用 - 传递值的形状是(x,y),索引暗示(w,z)【英文标题】:PYODBC to Pandas - DataFrame not working - Shape of passed values is (x,y), indices imply (w,z) 【发布时间】:2013-12-02 01:03:39 【问题描述】:我之前使用 pyodbc 和 python,但现在我已经将它安装在一台新机器上(win 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 版本,或者 pyodbc,但更新是有问题的。我试图更新一些模块,但它搞砸了一切,我使用的任何方法(二进制文件——用于正确的机器/安装——pip 安装、易于安装、任何东西!等等。这确实非常令人沮丧。我可能会避免从现在开始为 Python Win 8 64 位)。
实例:
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!
请帮忙 :) 谢谢!
【问题讨论】:
问题是……?temp
是干什么用的,data
来自哪里?
添加样本数据将提高答案的可能性。
当然,问题是如何摆脱错误并让 DataFrame(data,columns=columns) 工作。我在上面说过:我想要 (1,X) 其中 X 是列表的长度。
为什么需要指定列名? pandas 会自动检测到它们。 pandas.read_sql(query_string, cnxn_obj)
【参考方案1】:
这是因为游标返回的不是元组列表,而是 Row 对象的列表,它们实际上类似于元组,更好,但它们混淆了 pandas 数据帧构造函数。在原始示例中,在创建数据框之前执行此操作:
for i in range(0,len(temp)):
temp[i]=tuple(temp[i])
【讨论】:
Gena,你真是个天才。我花了几个小时在 SO 上尝试所有其他解决方案,而你的解决方案奏效了。df = pandas.DataFrame([tuple(t) for t in cursor.fetchall()])
恕我直言,这应该是公认的答案。 @MortenB 有一个漂亮的解决方案。
temp = map(tuple, temp)
更好【参考方案2】:
从 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)
【讨论】:
它给出了类似的错误!事实上,正如我所提到的,我的代码以前也可以工作。因此,一定是 pyodbc 改变了一些东西?文件“xxx.py”,第 253 行,在 xxx 结果中 = read_frame(sql,con);文件“C:\Python27\lib\site-packages\pandas\io\sql.py”,第 162 行,在 read_frame coerce_float=coerce_float) 文件“C:\Python27\lib\site-packages\pandas\core\frame. py”,第 1115 行,在 from_records 列中) 文件“C:\Python27\lib\site-packages\pandas\core\frame.py”,第 5338 行,在 _arrays_to_mgr 返回 create_block_manager_from_arrays(arrays,arr_names,axes) 文件“C:\Python27 \lib\site-packages\pandas\core\internals.py",第 1825 行,在 create_block_manager_from_arrays construction_error(len(arrays),arrays[0].shape[1:],axes) 文件“C:\Python27\lib\ site-packages\pandas\core\internals.py", line 1799, in construction_error tuple(map(int, [len(ax) for ax in axes])))) ValueError: 传递值的形状是 (51,),指数暗示 (51, 1402) 明确地说,这发生在我的所有机器上,2 台台式机和 1 台笔记本电脑。以前没有发生过(我更新了所有这些:/) @user1350191 我无法使用 pyodbc 3.0.6 重现此问题。当您尝试我的方法时,您能否编辑您的问题以确切地向我展示您在做什么? (显然,省略您的数据库密码等)。 它非常基本,与您所写的相似。只要我有大约 10 分钟的空闲时间,我就会看看我能做什么。同时,考虑到我在 Python 2.7 中使用了 pyodbc 3.0.7(32 位和 64 位都出现了同样的问题,pythonxy 和 anaconda 分布也是如此)。以上是关于PYODBC 到 Pandas - DataFrame 不起作用 - 传递值的形状是(x,y),索引暗示(w,z)的主要内容,如果未能解决你的问题,请参考以下文章
PYODBC 到 Pandas - DataFrame 不起作用 - 传递值的形状是(x,y),索引暗示(w,z)
PYODBC到Pandas - DataFrame不工作 - 传递值的形状是(x,y),索引暗示(w,z)