update1 25/01/2020: Ajouté ce comportement semblable à un bogue était un bogue
Depuis le 13/01/2020, pandas 1.0.0rc0 a été publié, mais l'une des fonctionnalités majeures est l'introduction de pd.NA
comme valeur manquante. Je vais résumer cette propriété et comment l'utiliser.
Avertissement: il a été confirmé qu'il fonctionne avec pandas 1.0.0 rc0, et il y a de fortes chances que cela change à l'avenir.
Enfin, [Environnement de vérification](#Verification Environment).
--pd.NA
apparaît comme la signification de la valeur manquante.
--pd.NA
peut être utilisé avec IntegerArray, BooleanArray, StringArray
--Avec l'introduction de pd.NA
, la valeur manquante peut être exprimée dans la classe int (pas de conversion imprudente en float).
--pd.NA
est un objet singleton et est cohérent avec tous les types de données.
--Toutes les valeurs de retour des opérateurs de comparaison pour pd.NA
sont pd.NA
(même comportement que pd.NA
dans Julia, NA
dans R).
pd.read_csv ()
, NA est reconnu en spécifiant ʻInt64,
string,
boolean. (
Booleanne fonctionne pas dans rc0 et traite des problèmes). Vous pouvez spécifier ~~, mais
boolean` entraînera une erreur. On ne sait pas si ce comportement est un bogue ou une spécification. (Probablement spécifications) ~~data type
Une nouvelle classe appelée NAType
est introduite dans les pandas. Le but est d'indiquer la valeur comme une valeur manquante.
>>> import pandas as pd
>>> pd.NA
<NA>
>>> type(pd.NA)
<class 'pandas._libs.missing.NAType'>
Dans pd.Series et pd.DataFrame, si vous ne spécifiez pas de type, il est traité comme un type d'objet, et si vous le spécifiez, il est traité comme ce type. ʻInt64Dtype est un entier Nullable (Un ExtensionDtype pour les données entières int64. Tableau de valeurs entières (facultatives manquantes)) introduit à partir de pandas 0.24. Notez que vous devez spécifier dtype en majuscules ʻInt64
au lieu de ʻint64`. Techniquement, l'introduction de «Pandas Extension Arrays» a permis d'utiliser ExtensionDType.
>>> pd.Series([pd.NA]).dtype
dtype('O') # O means Object
#Le dtype peut être spécifié soit comme un alias de chaîne, soit comme le type lui-même. Ce qui suit est spécifié sous forme de chaîne de caractères.
>>> pd.Series([pd.NA], dtype="Int64").dtype
Int64Dtype()
>>> pd.Series([pd.NA], dtype="boolean").dtype
BooleanDtype
>>> pd.Series([pd.NA], dtype="string").dtype
StringDtype
Cliquez ici pour l'implémentation de NAType
.
https://github.com/pandas-dev/pandas/blob/493363ef60dd9045888336b5c801b2a3d00e976d/pandas/_libs/missing.pyx#L335-L485
Fait intéressant, la valeur de hachage est définie par «2 ** 61 --1 == 2305843009213693951». Il n'y a pas de problème car il n'y a pas de conflit avec la clé du dictionnaire. Ce n'est pas lié à pd.NA
, mais en fait, le hachage des valeurs entières en python va avec 2 ** 61 -1
.
>>> hash(pd.NA) == 2 ** 61 -1
True
>>> {pd.NA: "a", 2305843009213693951: "b"}
{<NA>: 'a', 2305843009213693951: 'b'}
>>> (hash(2**61 - 2), hash(2**61 - 1), hash(2**61))
(2305843009213693950, 0, 1)
La détermination du type doit être spécifiée en majuscules ʻInt64 au lieu de ʻint64
.
>>> pd.Series([1, 2]) + pd.Series([pd.NA, pd.NA])
0 <NA>
1 <NA>
dtype: object
>>> pd.Series([1, 2]) + pd.Series([pd.NA, pd.NA], dtype="Int64")
0 <NA>
1 <NA>
dtype: Int64
Spécifier ʻint64` entraînera une erreur.
>>> pd.Series([pd.NA], dtype="int64").dtype
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.7/site-packages/pandas/core/series.py", line 304, in __init__
data = sanitize_array(data, index, dtype, copy, raise_cast_failure=True)
File "/usr/local/lib/python3.7/site-packages/pandas/core/construction.py", line 438, in sanitize_array
subarr = _try_cast(data, dtype, copy, raise_cast_failure)
File "/usr/local/lib/python3.7/site-packages/pandas/core/construction.py", line 535, in _try_cast
subarr = maybe_cast_to_integer_array(arr, dtype)
File "/usr/local/lib/python3.7/site-packages/pandas/core/dtypes/cast.py", line 1502, in maybe_cast_to_integer_array
casted = np.array(arr, dtype=dtype, copy=copy)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NAType'
Le résultat de l'opération avec booléen se comporte de la même manière que Julia's missing
et R's NA
.
>>> pd.Series([True, False, pd.NA]) & True
0 True
1 False
2 NA
dtype: bool
>>> pd.Series([True, False, pd.NA]) | True
0 True
1 True
2 True
dtype: bool
>>> pd.NA & True
NA
>>> pd.NA & False
False
>>> pd.NA | True
True
>>> pd.NA | False
NA
>>> pd.Series([1, 2, pd.NA], dtype="Int64")
0 1
1 2
2 <NA>
dtype: Int64
>>> pd.Series([True, False, pd.NA], dtype="boolean")
0 True
1 False
2 <NA>
dtype: boolean
Le résultat de l'opération de somme est "NA" propagé (propager), mais "pd.Series.sum ()" sans argument est traité comme "0" et n'est pas propagé. Il est nécessaire de spécifier sum (skipna = False)
pour le traiter comme propagate. Cependant, lors de la spécification du type de `` Int64 '', np.nan
était affiché à la place de NA
.
~~ J'ai cherché un problème pour voir s'il s'agissait du comportement attendu ou d'un bogue, mais ce n'était pas clair. J'ai donc créé imprudemment un ticket d'émission. ~~ ticket d'émission Importé. Cela semble se refléter dans rc1.
>>> sum([1, pd.NA])
<NA>
# pd.Series object
>>> pd.Series([1, pd.NA])
0 1
1 <NA>
dtype: object
>>> pd.Series([1, pd.NA]).sum()
1
>>> pd.Series([1, pd.NA]).sum(skipna=False)
<NA>
# pd.Series Int64
>>> pd.Series([1, pd.NA], dtype='Int64')
0 1
1 <NA>
dtype: Int64
>>> pd.Series([1, pd.NA], dtype='Int64').sum()
1
>>> pd.Series([1, pd.NA], dtype='Int64').sum(skipna=False)
nan
Le traitement des puissances est cohérent avec «NA_integer_» de R. Le comportement de Julia est un mystère.
>>> pd.NA ** 0
1
>>> 1 ** pd.NA
1
>>> -1 ** pd.NA
-1
> R.version.string
[1] "R version 3.6.1 (2019-07-05)"
> NA_integer_ ^ 0L
[1] 1
> 1L ^ NA_integer_
[1] 1
> -1L ^ NA_integer_
[1] -1
julia> VERSION
v"1.3.1"
julia> missing ^ 0
missing
julia> 1 ^ missing
missing
julia> -1 ^ missing
missing
Expérimentez avec le fichier csv suivant. (test.csv
)
X_int,X_bool,X_string
1,True,"a"
2,False,"b"
NA,NA,"NA"
Le comportement est le même que celui de pandas 0.25.3 sans spécifier dtype.
>>> df1 = pd.read_csv("test.csv")
>>> df1
X_int X_bool X_string
0 1.0 True a
1 2.0 False b
2 NaN NaN NaN
>>> df1.dtypes
X_int float64
X_bool object
X_string object
dtype: object
ʻInt64et
string` peuvent être spécifiés pour dtype.
#dtype peut être la classe de type suivante au lieu d'un littéral de caractère.
# df2 = pd.read_csv("test.csv", dtype={'X_int': pd.Int64Dtype(), 'X_string': pd.StringDtype()})
>>> df2 = pd.read_csv("test.csv", dtype={'X_int': 'Int64', 'X_string': 'string'})
>>> df2
X_int X_bool X_string
0 1 True a
1 2 False b
2 <NA> NaN <NA>
>>> df2.dtypes
X_int Int64
X_bool object
X_string string
dtype: object
D'un autre côté, même si boolean '' `pd.BooleanDtype ()` est spécifié, la lecture en tant que booléen NA échoue. Bien sûr, spécifier
'bool' 'est également une erreur. problème Lorsque je l'ai signalé, il a été importé avec succès. Cela semble fonctionner correctement avec rc1.
>>> df3 = pd.read_csv("test.csv", dtype={'X_bool': 'boolean'})
Traceback (most recent call last):
File "pandas/_libs/parsers.pyx", line 1191, in pandas._libs.parsers.TextReader._convert_with_dtype
File "/usr/local/lib/python3.7/site-packages/pandas/core/arrays/base.py", line 232, in _from_sequence_of_strings
raise AbstractMethodError(cls)
pandas.errors.AbstractMethodError: This method must be defined in the concrete class type
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.7/site-packages/pandas/io/parsers.py", line 676, in parser_f
return _read(filepath_or_buffer, kwds)
File "/usr/local/lib/python3.7/site-packages/pandas/io/parsers.py", line 454, in _read
data = parser.read(nrows)
File "/usr/local/lib/python3.7/site-packages/pandas/io/parsers.py", line 1133, in read
ret = self._engine.read(nrows)
File "/usr/local/lib/python3.7/site-packages/pandas/io/parsers.py", line 2037, in read
data = self._reader.read(nrows)
File "pandas/_libs/parsers.pyx", line 859, in pandas._libs.parsers.TextReader.read
File "pandas/_libs/parsers.pyx", line 874, in pandas._libs.parsers.TextReader._read_low_memory
File "pandas/_libs/parsers.pyx", line 951, in pandas._libs.parsers.TextReader._read_rows
File "pandas/_libs/parsers.pyx", line 1083, in pandas._libs.parsers.TextReader._convert_column_data
File "pandas/_libs/parsers.pyx", line 1114, in pandas._libs.parsers.TextReader._convert_tokens
File "pandas/_libs/parsers.pyx", line 1194, in pandas._libs.parsers.TextReader._convert_with_dtype
NotImplementedError: Extension Array: <class 'pandas.core.arrays.boolean.BooleanArray'> must implement _from_sequence_of_strings in order to be used in parser methods
>>> df3 = pd.read_csv("test.csv", dtype={'X_bool': pd.BooleanDtype()})
Traceback (most recent call last):
File "pandas/_libs/parsers.pyx", line 1191, in pandas._libs.parsers.TextReader._convert_with_dtype
File "/usr/local/lib/python3.7/site-packages/pandas/core/arrays/base.py", line 232, in _from_sequence_of_strings
raise AbstractMethodError(cls)
pandas.errors.AbstractMethodError: This method must be defined in the concrete class type
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.7/site-packages/pandas/io/parsers.py", line 676, in parser_f
return _read(filepath_or_buffer, kwds)
File "/usr/local/lib/python3.7/site-packages/pandas/io/parsers.py", line 454, in _read
data = parser.read(nrows)
File "/usr/local/lib/python3.7/site-packages/pandas/io/parsers.py", line 1133, in read
ret = self._engine.read(nrows)
File "/usr/local/lib/python3.7/site-packages/pandas/io/parsers.py", line 2037, in read
data = self._reader.read(nrows)
File "pandas/_libs/parsers.pyx", line 859, in pandas._libs.parsers.TextReader.read
File "pandas/_libs/parsers.pyx", line 874, in pandas._libs.parsers.TextReader._read_low_memory
File "pandas/_libs/parsers.pyx", line 951, in pandas._libs.parsers.TextReader._read_rows
File "pandas/_libs/parsers.pyx", line 1083, in pandas._libs.parsers.TextReader._convert_column_data
File "pandas/_libs/parsers.pyx", line 1114, in pandas._libs.parsers.TextReader._convert_tokens
File "pandas/_libs/parsers.pyx", line 1194, in pandas._libs.parsers.TextReader._convert_with_dtype
NotImplementedError: Extension Array: <class 'pandas.core.arrays.boolean.BooleanArray'> must implement _from_sequence_of_strings in order to be used in parser methods
>>> df3 = pd.read_csv("test.csv", dtype={'X_bool': 'bool'})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.7/site-packages/pandas/io/parsers.py", line 676, in parser_f
return _read(filepath_or_buffer, kwds)
File "/usr/local/lib/python3.7/site-packages/pandas/io/parsers.py", line 454, in _read
data = parser.read(nrows)
File "/usr/local/lib/python3.7/site-packages/pandas/io/parsers.py", line 1133, in read
ret = self._engine.read(nrows)
File "/usr/local/lib/python3.7/site-packages/pandas/io/parsers.py", line 2037, in read
data = self._reader.read(nrows)
File "pandas/_libs/parsers.pyx", line 859, in pandas._libs.parsers.TextReader.read
File "pandas/_libs/parsers.pyx", line 874, in pandas._libs.parsers.TextReader._read_low_memory
File "pandas/_libs/parsers.pyx", line 951, in pandas._libs.parsers.TextReader._read_rows
File "pandas/_libs/parsers.pyx", line 1083, in pandas._libs.parsers.TextReader._convert_column_data
File "pandas/_libs/parsers.pyx", line 1114, in pandas._libs.parsers.TextReader._convert_tokens
File "pandas/_libs/parsers.pyx", line 1231, in pandas._libs.parsers.TextReader._convert_with_dtype
ValueError: Bool column has NA values in column 1
(Impression) Tout le coupable était que la valeur manquante n'existait pas dans numpy. Il y a donc diverses incohérences dans l'introduction au niveau de la couche pandas. Diverses choses sont écrites ici. https://dev.pandas.io/docs/user_guide/gotchas.html#why-not-make-numpy-like-r
J'ai remarqué par retweet de quelqu'un sur Twitter
https://mobile.twitter.com/jorisvdbossche/status/1208476049690046465
--pd.NA
apparaît comme la signification de la valeur manquante.
--pd.NA
peut être utilisé avec IntegerArray, BooleanArray, StringArray
--Avec l'introduction de pd.NA
, la valeur manquante peut être exprimée dans la classe int (pas de conversion imprudente en float).
--pd.NA
est un objet singleton et est cohérent avec tous les types de données.
--Toutes les valeurs de retour de l'opérateur de comparaison pour pd.NA sont pd.NA
(même comportement que l'objet manquant
de Julia, R`` NA`))
pd.read_csv ()
, ʻInt64 et
stringpeuvent être spécifiés, mais
boolean` devient une erreur. On ne sait pas si ce comportement est un bogue ou une spécification. (Probablement spécifications)Si vous aimez ce genre d'histoire maniaque, venez nous rendre visite à justInCase. https://www.wantedly.com/companies/justincase
Je l'ai confirmé sur docker.
FROM python:3.7.6
WORKDIR /home
RUN pip install pandas==1.0.0rc0
CMD ["/bin/bash"]
$ docker build -t pdna .
$ docker run -it --rm -v $(pwd):/home/ pdna
Inside Docker
root@286578c2496b:/home# cat /etc/issue
Debian GNU/Linux 10 \n \l
root@286578c2496b:/home# uname -a
Linux 286578c2496b 4.9.184-linuxkit #1 SMP Tue Jul 2 22:58:16 UTC 2019 x86_64 GNU/Linux
root@286578c2496b:/home# python -c "import pandas as pd; pd.show_versions()"
INSTALLED VERSIONS
------------------
commit : None
python : 3.7.6.final.0
python-bits : 64
OS : Linux
OS-release : 4.9.184-linuxkit
machine : x86_64
processor :
byteorder : little
LC_ALL : None
LANG : C.UTF-8
LOCALE : en_US.UTF-8
pandas : 1.0.0rc0
numpy : 1.18.1
pytz : 2019.3
dateutil : 2.8.1
pip : 19.3.1
setuptools : 44.0.0
Cython : None
pytest : None
hypothesis : None
sphinx : None
blosc : None
feather : None
xlsxwriter : None
lxml.etree : None
html5lib : None
pymysql : None
psycopg2 : None
jinja2 : None
IPython : None
pandas_datareader: None
bs4 : None
bottleneck : None
fastparquet : None
gcsfs : None
lxml.etree : None
matplotlib : None
numexpr : None
odfpy : None
openpyxl : None
pandas_gbq : None
pyarrow : None
pytables : None
pytest : None
s3fs : None
scipy : None
sqlalchemy : None
tables : None
tabulate : None
xarray : None
xlrd : None
xlwt : None
xlsxwriter : None
numba : None
Recommended Posts