Soy nuevo en Julia y tengo una función de Python que quiero usar en Julia. Básicamente, lo que hace la función es aceptar un marco de datos (pasado como un ndarray numpy), un valor de filtro y una lista de índices de columna (de la matriz) y ejecutar una regresión logística usando el paquete statsmodels en Python. Hasta ahora he intentado esto:

using PyCall

py"""
import pandas as pd
import numpy as np
import random
import statsmodels.api as sm
import itertools
def reg_frac(state, ind_vars):
    rows = 2000
    total_rows = rows*13
    data = pd.DataFrame({
    'state': ['a', 'b', 'c','d','e','f','g','h','i','j','k','l','m']*rows, \
    'y_var': [random.uniform(0,1) for i in range(total_rows)], \
    'school': [random.uniform(0,10) for i in range(total_rows)], \
    'church': [random.uniform(11,20) for i in range(total_rows)]}).to_numpy()
    try:
        X, y = sm.add_constant(np.array(data[(data[:,0] == state)][:,ind_vars], dtype=float)), np.array(data[(data[:,0] == state), 1], dtype=float)
        model = sm.Logit(y, X).fit(cov_type='HC0', disp=False)      
        rmse = np.sqrt(np.square(np.subtract(y, model.predict(X))).mean())
    except:
        rmse = np.nan
    return [state, ind_vars, rmse] 
"""

reg_frac(state, ind_vars) = (py"reg_frac"(state::Char, ind_vars::Array{Any}))

Sin embargo, cuando ejecuto esto, no espero que los resultados sean NaN. Creo que está funcionando pero me falta algo.

reg_frac('b', Any[i for i in 2:3])

  0.000244 seconds (249 allocations: 7.953 KiB)
3-element Array{Any,1}:
    'b'
    [2, 3]
 NaN

Cualquier ayuda es apreciada.

2
Kay 1 sep. 2020 a las 14:30

1 respuesta

La mejor respuesta

En el código Python tienes str s mientras que en el código Julia tienes Char s - no es lo mismo.

Python:

>>> type('a')
<class 'str'>

Julia

julia> typeof('a')
Char

Por tanto, sus comparaciones no funcionan. Tu función podría verse así:

reg_frac(state, ind_vars) = (py"reg_frac"(state::String, ind_vars::Array{Any}))

Y ahora:

julia> reg_frac("b", Any[i for i in 2:3])
3-element Array{Any,1}:
  "b"
  [2, 3]
 0.2853707270515166

Sin embargo, recomiendo usar Vector{Float64} que en PyCall se convierte en vuelo en un vector numpy en lugar de usar Vector{Any} por lo que parece que su código aún podría mejorarse (dependiendo de lo que realmente esté planeando hacer) .

1
Przemyslaw Szufel 2 sep. 2020 a las 17:10