【问题标题】:Linear regression with pandas dataframe使用 pandas 数据框进行线性回归
【发布时间】:2013-10-23 03:26:52
【问题描述】:

我在 pandas 中有一个用于生成散点图的数据框,并希望为该图添加一条回归线。现在我正在尝试用 polyfit 做到这一点。

这是我的代码:

import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
from numpy import *

table1 = pd.DataFrame.from_csv('upregulated_genes.txt', sep='\t', header=0, index_col=0)
table2 = pd.DataFrame.from_csv('misson_genes.txt', sep='\t', header=0, index_col=0)
table1 = table1.join(table2, how='outer')

table1 = table1.dropna(how='any')
table1 = table1.replace('#DIV/0!', 0)

# scatterplot
plt.scatter(table1['log2 fold change misson'], table1['log2 fold change'])
plt.ylabel('log2 expression fold change')
plt.xlabel('log2 expression fold change Misson et al. 2005')
plt.title('Root Early Upregulated Genes')
plt.axis([0,12,-5,12])

# this is the part I'm unsure about
regres = polyfit(table1['log2 fold change misson'], table1['log2 fold change'], 1)

plt.show()

但我收到以下错误:

TypeError: cannot concatenate 'str' and 'float' objects

有人知道我在哪里出错了吗?我也不确定如何将回归线添加到我的情节中。我的代码中的任何其他通用 cmets 也将不胜感激,我仍然是初学者。

【问题讨论】:

  • 你在哪一行得到错误?
  • @usethedeathstar regres = polyfit(table1['log2 fold change misson'], table1['log2 fold change'], 1)
  • 确定表中没有 NaN 值?因为 pylab.scatter 只是不绘制 x 或 y 为 NaN 的 x,y 点(这意味着它也不会给出错误),但也许 polyfit 不知道? (只是猜测问题可能出在哪里 - 非数字值如何存储在您的 csv 文件中?)
  • 不,没有 NaN 值。唯一的非数字值是“#DIV/0!”,我将其删除
  • table1['log2 fold change misson'] 和 table1['log2 fold change'] 的类型是什么? (据我所知,它们应该是 numpy.array,float 作为 dtype(并且两者都应该具有相同的形状))

标签: python numpy matplotlib pandas regression


【解决方案1】:

而不是替换“#DIV/0!”手动强制数据为数字。这同时做了两件事:它确保结果是数字类型(不是 str),它用NaN 替换任何不能被解析为数字的条目。示例:

In [5]: Series([1, 2, 'blah', '#DIV/0!']).convert_objects(convert_numeric=True)
Out[5]: 
0     1
1     2
2   NaN
3   NaN
dtype: float64

这应该可以解决您的错误。但是,在将一条线拟合到数据的一般主题上,我有两种比 polyfit 更喜欢的方法。两者中的第二个更健壮(并且可能会返回有关统计数据的更详细信息),但它需要 statsmodels。

from scipy.stats import linregress
def fit_line1(x, y):
    """Return slope, intercept of best fit line."""
    # Remove entries where either x or y is NaN.
    clean_data = pd.concat([x, y], 1).dropna(0) # row-wise
    (_, x), (_, y) = clean_data.iteritems()
    slope, intercept, r, p, stderr = linregress(x, y)
    return slope, intercept # could also return stderr

import statsmodels.api as sm
def fit_line2(x, y):
    """Return slope, intercept of best fit line."""
    X = sm.add_constant(x)
    model = sm.OLS(y, X, missing='drop') # ignores entires where x or y is NaN
    fit = model.fit()
    return fit.params[1], fit.params[0] # could also return stderr in each via fit.bse

要绘制它,请执行以下操作

m, b = fit_line2(x, y)
N = 100 # could be just 2 if you are only drawing a straight line...
points = np.linspace(x.min(), x.max(), N)
plt.plot(points, m*points + b)

【讨论】:

  • 谢谢!强制数据为数字已经修复了我得到的错误,但是我从 polyfit 和你建议的代码中得到了 NaN 输出......知道为什么会这样吗?
  • 一些 NaN,还是所有 NaN?你能用你的一小部分数据重现问题,并在这里分享吗?
  • 对不起,这只是我的一个错误,它现在正在工作。你知道我如何将它作为一条线添加到我的散点图中吗?
  • 查看我的答案底部。如果它没有出现在同一个图中,请尝试在 plot 中添加关键字参数 ax=plt.gca()。
猜你喜欢
  • 2015-06-27
  • 2016-04-25
  • 2016-07-21
  • 2020-06-11
  • 2018-07-31
  • 2014-08-26
  • 2013-11-28
  • 2021-12-20
相关资源
最近更新 更多