Regresión lineal con dataframe pandas.

Tengo un dataframe en pandas que estoy usando para producir un diagtwig de dispersión, y quiero incluir una línea de regresión para la gráfica. En este momento estoy tratando de hacer esto con Polyfit.

Aquí está mi código:

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() 

Pero me sale el siguiente error:

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

¿Alguien sabe dónde me voy mal aquí? Tampoco estoy seguro de cómo agregar la línea de regresión a mi gráfica. Cualquier otro comentario general sobre mi código también sería muy apreciado, todavía soy un principiante.

En lugar de reemplazar ‘# DIV / 0!’ A mano, obliga a que los datos sean numéricos. Esto hace dos cosas a la vez: asegura que el resultado sea de tipo numérico (no str), y sustituye a NaN por cualquier entrada que no se pueda analizar como un número. Ejemplo:

 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 

Esto debería arreglar su error. Pero, sobre el tema general de ajustar una línea a los datos, tengo a mano dos formas de hacer esto que me gustan más que polyfit. El segundo de los dos es más robusto (y potencialmente puede devolver información mucho más detallada sobre las estadísticas) pero requiere modelos de estadísticas.

 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 

Para trazarlo, haz algo como

 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)