Могут ли pandas обрезать мои данные и вызвать непоправимую потерю данных без какого-либо предупреждения вообще?

#python #pandas #floating-point #truncate

#python #панды #с плавающей запятой #усечь

Вопрос:

 import pandas as pd
import io

indata = io.StringIO("cn10000000000")

df = pd.read_csv(indata, header=0)
print(df)

indata.seek(0)

df = pd.read_csv(indata, header=0, dtype={"c":int})
print(df)
 

Ожидаемый результат:

              c
0  10000000000
            c
0  10000000000
 

Фактический объем производства:

              c
0  10000000000
            c
0  1410065408
 

Могут ли pandas усекать мои данные таким образом без какого-либо предупреждения?

Я бился головой, пытаясь понять, почему мой сценарий не сработал (конечно, это игрушечный пример. Мой сценарий более сложный). После 45 минут отчаяния (пытаясь также определить тип данных, который pandas присвоил моим столбцам) Я только что обнаружил поведение, описанное выше.

Я установил значение dtype в своем реальном скрипте, потому что pandas продолжал загружать этот столбец как a float , но он был нужен мне как a int для сравнения.

РЕДАКТИРОВАТЬ: Дополнительная информация, запрошенная в комментариях:

Версия Python

 Python 3.8.5 (default, Sep  3 2020, 21:29:08) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on win32
 

Версия Pandas: 1.1.3

Платформа:

 >>> platform.platform()
'Windows-10-10.0.18362-SP0'
>>> platform.processor()
'Intel64 Family 6 Model 158 Stepping 10, GenuineIntel'
>>> platform.version()
'10.0.18362'
 

Комментарии:

1. У меня в версии pandas работает нормально '1.0.5'

2. @sushanth может быть, это вызвано платформой? У меня есть conda с Python 3.8 в Windows 10 x64

3. @sushanth я думаю, что единственный способ работать для вас — это иметь 64-разрядный int по умолчанию… какую платформу вы используете?

4. печать platform.platform() , platform.processor() и, возможно platform.version() , дал бы больше подробностей.

5. У меня тоже все хорошо работает. мой pd.__version__ -> 1.1.4 , ubuntu 20.04 focal fosa

Ответ №1:

Я вижу, что здесь происходит. Из документации pandas:

dtypeType name или dict столбца -> тип, необязательный тип данных для данных или столбцов. Например. {‘a’: np.float64, ‘b’: np.int32, ‘c’: ‘Int64’} Используйте str или object вместе с подходящими na_values настройками для сохранения и не интерпретации dtype. Если указаны конвертеры, они будут применены ВМЕСТО преобразования dtype.

Итак, заглавными БУКВАМИ указано, что read_csv() будет использоваться конвертер dtype, если вы его укажете. Итак, передача int похожа на явное указание использовать эквивалент numpy int . Вот почему нет предупреждений, и это следует считать ожидаемым поведением.


Теперь вопрос в том, почему мой numpy-эквивалент int is int32 вместо int64 ?

Numpy (doc) сопоставляет python int со встроенным скаляром np.int_ со следующим предупреждением:

введите описание изображения здесь

В документации numpy указано, что встроенный скаляр np.int_ зависит от платформы:

введите описание изображения здесь

TL; DR int(python) -> int_(numpy) -> long(C)

Итак, вопрос в том, что это long значит для вашей системы?

Для MSC long это 4 байта, как показано в документах:

введите описание изображения здесь

и подтверждено numpy:

введите описание изображения здесь

Для GCC long это 8 байт, как подтверждено здесь:

введите описание изображения здесь


Надеюсь, это было полезно, и вы узнали что-то новое. 🙂

Комментарии:

1. Я прочитаю это более внимательно позже, но все же для меня НЕОБЪЯСНИМО, почему панды молчат… Я НИКОГДА НЕ ОЖИДАЮ, что ОН вырежет и усечет мои данные и приведет к потере данных молча