遍历并将Pandas DataFrame中的NaN写回MySQL

1 投票
1 回答
2672 浏览
提问于 2025-04-17 13:19

我正在尝试把回归的结果写入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 个回答

3

我没有完整的答案,但我有一些小建议可能会对你有帮助。我觉得你把你的 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)

希望这些对你有帮助。

撰写回答