遍历并将Pandas DataFrame中的NaN写回MySQL
我正在尝试把回归的结果写入MySQL,但在处理拟合值时遇到了一些问题,特别是想把NaN(缺失值)写成null值。最开始,我是这样进行迭代的:
for i in dataframe:
cur = cnx.cursor()
query = ("UPDATE Regression_Data.Input SET FITTEDVALUES="+(dataframe['yhat'].__str__())+" where timecount="+(datafrane['timecount'].__str__())+";")
cur.execute(query)
cnx.commit()
cur.close()
.....结果SQL给我反馈说:
"mysql.connector.errors.ProgrammingError: 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NaN'
所以,我试着通过只让Python在yhat不等于NaN时才提交数据来过滤掉NaN:
for i in dataframe:
if cleandf['yhat']>(-1000):
cur = cnx.cursor()
query = ("UPDATE Regression_Data.Input SET FITTEDVALUES="+(dataframe['yhat'].__str__())+" where timecount="+(datafrane['timecount'].__str__())+";")
cur.execute(query)
cnx.commit()
cur.close()
但这样我得到了这个结果:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
于是,我在上面的语法中尝试用这个方法来解决:
if cleandf['yhat'][i]>(-1000):
但结果还是这样:
ValueError: Can only tuple-index with a MultiIndex
然后我尝试在两个地方都加上itterows(),像这样:
for i in dataframe.iterrows():
if cleandf['yhat'][i]>(-1000):
但还是遇到了和之前一样的问题。
我不太确定我哪里出错了,但我猜可能是和在Pandas DataFrame中进行迭代有关。不过,即使我把迭代做对了,我也想在NaN出现的地方写入Null到SQL中。
你觉得我应该怎么做呢?
1 个回答
我没有完整的答案,但我有一些小建议可能会对你有帮助。我觉得你把你的 dataframe
看成了类似于 SQL 记录集的对象。
for i in dataframe
这段代码会遍历数据框中的列名字符串。这里的 i
会代表列名,而不是行。
dataframe['yhat']
这段代码会返回整列数据(pandas.Series
,其实就是 numpy.ndarray
),而不是单个值。所以:
dataframe['yhat'].__str__()
这会给出整列的字符串表示,方便人类阅读。它绝对不是一个可以转换成字符串的单一值,适合你的查询。
if cleandf['yhat']>(-1000)
这会报错,因为 cleandf['yhat']
是一整列的值,而不仅仅是一个单独的值。可以把它想象成一整列,而不是单行的值。
if cleandf['yhat'][i]>(-1000):
这已经接近了,但你其实希望 i
在这里是一个整数,而不是另一个列名。
for i in dataframe.iterrows():
if cleandf['yhat'][i]>(-1000):
使用 iterrows
似乎是个不错的选择。不过,这里的 i
代表的是每一行的值,而不是可以用来索引列的整数(cleandf['yhat']
是一整列)。
另外,注意 pandas 有更好的方法来检查缺失值,而不是依赖一个巨大的负数。试试这样的代码:
non_missing_index = pandas.isnull(dataframe['yhat'])
cleandf = dataframe[non_missing_index]
for row in cleandf.iterrows():
row_index, row_values = row
query = ("UPDATE Regression_Data.Input SET FITTEDVALUES="+(row_values['yhat'].__str__())+" where timecount="+(row_values['timecount'].__str__())+";")
execute_my_query(query)
我相信你能比我更好地实现 execute_my_query
。不过,这个解决方案并不是你想要的。你其实想要遍历所有行,并进行两种类型的插入。试试这个:
for row in dataframe.iterrows():
row_index, row_values = row
if pandas.isnull(row_values['yhat']):
pass # populate the 'null' insert query here
else:
query = ("UPDATE Regression_Data.Input SET FITTEDVALUES="+(row_values['yhat'].__str__())+" where timecount="+(row_values['timecount'].__str__())+";")
execute_my_query(query)
希望这些对你有帮助。