2014-04-29 27 views
9

我试图从ascii中读取几百个表,然后将它们写入到mySQL。这似乎很容易与熊猫做,但我碰到一个错误,对我来说没有意义:Python Pandas使用NaN值写入sql

我有一个8列的数据帧。下面是列的列表/索引:

metricDF.columns 

Index([u'FID', u'TYPE', u'CO', u'CITY', u'LINENO', u'SUBLINE', u'VALUE_010', u'VALUE2_015'], dtype=object) 

然后我用to_sql将数据追加直到MySQL

metricDF.to_sql(con=con, name=seqFile, if_exists='append', flavor='mysql') 

我得到一个奇怪的错误有关的列是“南”:

OperationalError: (1054, "Unknown column 'nan' in 'field list'") 

正如你可以看到我所有的列都有名字。我意识到mysql/sql支持写作出现在开发中,所以也许这就是原因?如果有,还有解决方法吗?任何建议将不胜感激。

回答

18

更新:首先是熊猫0.15,to_sql支持写入NaN值(它们会在数据库中写为NULL),所以不应该不再需要下面描述的解决方法(见https://github.com/pydata/pandas/pull/8208)。
Pandas 0.15将于10月份发布,该功能将在开发版本中合并。


这可能是由于您的表NaN值,这是目前已知的缺点是,大熊猫SQL函数不处理好的NaN(https://github.com/pydata/pandas/issues/2754https://github.com/pydata/pandas/issues/4199

作为一种变通方法在这一刻(大熊猫版本0.14.1,下),您可以手动将nan值转换为无有:

df2 = df.astype(object).where(pd.notnull(df), None) 

,然后写数据框为SQL。然而,这将所有列转换为对象dtype。因此,您必须根据原始数据框创建数据库表。使用以前的解决方案将列D型改变从float64到object_

df[:1].to_sql('table_name', con) 
df2[1:].to_sql('table_name', con, if_exists='append') 
+0

太棒了!完全合作。你必须像这样爱一个简单的线路解决方案。谢谢。 – user3221876

+0

请注意,此解决方法不会从datetime64列中删除NaT值(至少在我尝试过时不会) – aensm

+0

@aensm感谢您的注意,此错误也将在0.15中解决。 – joris

2

:例如,如果你的第一行不包含NaN秒。

我已经找到了更好的解决方案,只需添加以下_write_mysql功能:

from pandas.io import sql 

def _write_mysql(frame, table, names, cur): 
    bracketed_names = ['`' + column + '`' for column in names] 
    col_names = ','.join(bracketed_names) 
    wildcards = ','.join([r'%s'] * len(names)) 
    insert_query = "INSERT INTO %s (%s) VALUES (%s)" % (
     table, col_names, wildcards) 

    data = [[None if type(y) == float and np.isnan(y) else y for y in x] for x in frame.values] 

    cur.executemany(insert_query, data) 

,然后覆盖其在熊猫如下实施:

sql._write_mysql = _write_mysql 

有了这个代码,NaN值会在不更改列类型的情况下正确保存在数据库中。

+1

请注意,这不适用于熊猫0。14及以上(在熊猫0.14有一个重构) – joris

+0

我刚刚发现。我试图找到类似的熊猫解决方案0.14 –

+1

您可以例如在'maybe_asscalar'中进行检查(https://github.com/pydata/pandas/blob/master/pandas/io/sql.py#L580) – joris

-1

NaT到MySQL仍然没有在熊猫处理15.2

+0

如果遇到特定问题,您可以在https://github.com/pydata/pandas/issues上打开问题吗?由于这应该是行得通的,我们希望得到一个错误报告。 – joris