Регрессии, которые будут работать с типами numpy int и даже с типами bool, в случае сбоя типов pandas int с TypeError: data type not understood
Пример кода
import statsmodels.formula.api as smf
import pandas as pd
df = pd.DataFrame({"y": [0.02, 0.011, 0.01, 0.06, 0.12, 0.015],
"x": [False, False, False, True, True, False]
})
df["x2"] = df["x"].astype('int8')
df["x3"] = df["x"].astype('Int8')
print(df)
print([df[col].dtype for col in df.columns])
model = smf.logit(formula="y ~ x", data=df) #This works.
print(model.fit().summary())
model = smf.logit(formula="y ~ x2", data=df) #This works too.
print(model.fit().summary())
model = smf.logit(formula="y ~ x3", data=df) #This does not work.
print(model.fit().summary())
Примечание: Не берите в голову значения, размеры выборки и доброту в этих регрессиях, я знаю, что они бесполезны. Они предназначены в качестве минимального воспроизводимого примера.
Пример вывода
$ python3 regtest.py
y x x2 x3
0 0.020 False 0 0
1 0.011 False 0 0
2 0.010 False 0 0
3 0.060 True 1 1
4 0.120 True 1 1
5 0.015 False 0 0
[dtype('float64'), dtype('bool'), dtype('int8'), Int8Dtype()]
Optimization terminated successfully.
Current function value: 0.057534
Iterations 8
/usr/lib/python3.7/site-packages/statsmodels/discrete/discrete_model.py:3390: RuntimeWarning: divide by zero encountered in double_scalars
return 1 - self.llf/self.llnull
Logit Regression Results
==============================================================================
Dep. Variable: y No. Observations: 6
Model: Logit Df Residuals: 4
Method: MLE Df Model: 1
Date: Wed, 30 Oct 2019 Pseudo R-squ.: inf
Time: 20:01:22 Log-Likelihood: -0.34520
converged: True LL-Null: 0.0000
Covariance Type: nonrobust LLR p-value: 1.000
==============================================================================
coef std err z P>|z| [0.025 0.975]
------------------------------------------------------------------------------
Intercept -4.2546 4.256 -1.000 0.317 -12.596 4.086
x[T.True] 1.9410 4.921 0.394 0.693 -7.704 11.586
==============================================================================
Optimization terminated successfully.
Current function value: 0.057534
Iterations 8
/usr/lib/python3.7/site-packages/statsmodels/discrete/discrete_model.py:3390: RuntimeWarning: divide by zero encountered in double_scalars
return 1 - self.llf/self.llnull
Logit Regression Results
==============================================================================
Dep. Variable: y No. Observations: 6
Model: Logit Df Residuals: 4
Method: MLE Df Model: 1
Date: Wed, 30 Oct 2019 Pseudo R-squ.: inf
Time: 20:01:22 Log-Likelihood: -0.34520
converged: True LL-Null: 0.0000
Covariance Type: nonrobust LLR p-value: 1.000
==============================================================================
coef std err z P>|z| [0.025 0.975]
------------------------------------------------------------------------------
Intercept -4.2546 4.256 -1.000 0.317 -12.596 4.086
x2 1.9410 4.921 0.394 0.693 -7.704 11.586
==============================================================================
Traceback (most recent call last):
File "regtest.py", line 16, in <module>
model = smf.logit(formula="y ~ x3", data=df)
File "/usr/lib/python3.7/site-packages/statsmodels/base/model.py", line 159, in from_formula
missing=missing)
File "/usr/lib/python3.7/site-packages/statsmodels/formula/formulatools.py", line 65, in handle_formula_data
NA_action=na_action)
File "/usr/lib/python3.7/site-packages/patsy/highlevel.py", line 310, in dmatrices
NA_action, return_type)
File "/usr/lib/python3.7/site-packages/patsy/highlevel.py", line 165, in _do_highlevel_design
NA_action)
File "/usr/lib/python3.7/site-packages/patsy/highlevel.py", line 70, in _try_incr_builders
NA_action)
File "/usr/lib/python3.7/site-packages/patsy/build.py", line 696, in design_matrix_builders
NA_action)
File "/usr/lib/python3.7/site-packages/patsy/build.py", line 448, in _examine_factor_types
done = cat_sniffers[factor].sniff(value)
File "/usr/lib/python3.7/site-packages/patsy/categorical.py", line 198, in sniff
if hasattr(data, "dtype") and safe_issubdtype(data.dtype, np.bool_):
File "/usr/lib/python3.7/site-packages/patsy/util.py", line 710, in safe_issubdtype
return np.issubdtype(dt1, dt2)
File "/usr/lib/python3.7/site-packages/numpy/core/numerictypes.py", line 393, in issubdtype
arg1 = dtype(arg1).type
TypeError: data type not understood
Зачем мне это нужно? Чтобы сэкономить память,Я могу захотеть преобразовать данные, которые содержат NaN
s, в целочисленные типы при сохранении NaN
s. Есть вопрос об этом ;ответ рекомендует df[col].astype("Int32")
как самое простое решение. Типы данных с плавающей запятой могут потреблять много памяти, если у меня много наблюдений, поэтому вместо них было бы желательно использовать маленькие целочисленные типы. Конечно, я мог бы удалить NaN
s вручную, а затем использовать пустые типы, но это много хлопот, потенциальный источник ошибок и, я думаю, тоже не очень питонический.
Программное обеспечение Ядро Linux 5.3.7, Python 3.7.4, Pandas 0.25.2, Statsmodels 0.10.1