Как получить согласованные dtypes после to_csv и read_csv? - PullRequest
4 голосов
/ 10 июля 2019

UPDATE

Ответ TomNash решает вопрос в соответствии с заданным вопросом. Однако попытка использовать его в моей реальной проблеме привела к проблемам с именами столбцов в кавычках, проблемам, когда отсутствовали данные и т. Д. Чтобы обойти это, я использую предложение CJR в комментариях, чтобы просто перебирать мои DataFrames.

ОРИГИНАЛЬНЫЙ ВОПРОС НИЖЕ :

У меня есть DataFrame Panda в памяти. Я хотел бы иметь возможность записать его в файл (используя to_csv), а затем использовать read_csv, чтобы прочитать результаты в новый DataFrame. Я хотел бы, чтобы исходный DataFrame и новый "из файла DataFrame" имели идентичные типы данных.

Я попытался заставить это работать, используя аргументы quoting и quotechar для to_csv и read_csv. Однако, похоже, это не помогает.

Я понимаю, что для read_csv аргумент dtype может использоваться для принудительного использования типов данных, но это не практично для моего случая использования (множество автоматически сгенерированных файлов, используемых для регрессионного тестирования).

Полный пример ниже.

tmp.py

import pandas as pd
from csv import QUOTE_NONNUMERIC
import sys

print('Python version information:')
print(sys.version)
print('Pandas version information:')
print(pd.__version__)

df1 = pd.DataFrame([['A', '100', 100], ['B', '200', 200]])
print('df1:')
print(df1.info())

df1.to_csv('tmp.csv', index=False, quoting=QUOTE_NONNUMERIC,
           quotechar='"')

df2 = pd.read_csv('tmp.csv', quoting=QUOTE_NONNUMERIC, quotechar='"')
print('df2:')
print(df2.info())

Выход из режима работы tmp.py:

Python version information:
3.7.3 (default, Jun 11 2019, 01:11:15) 
[GCC 6.3.0 20170516]
Pandas version information:
0.24.2
df1:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2 entries, 0 to 1
Data columns (total 3 columns):
0    2 non-null object
1    2 non-null object
2    2 non-null int64
dtypes: int64(1), object(2)
memory usage: 128.0+ bytes
None
df2:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2 entries, 0 to 1
Data columns (total 3 columns):
0    2 non-null object
1    2 non-null float64
2    2 non-null float64
dtypes: float64(2), object(1)
memory usage: 128.0+ bytes
None
  1. Столбец 1: Как и ожидалось, dtype составляет object для обоих фреймов данных.
  2. Колонка 2: Неожиданное поведение. Для df1 dtype равен object, а для df2 dtype равен float64.
  3. Колонка 3: Ожидаемое поведение. df1 имеет dtype int64, тогда как df2 имеет dtype float64. Как описывает csv модуль , csv.QUOTE_NONNUMERIC «Указывает читателю преобразовать все поля без кавычек в тип float.»

Содержимое tmp.csv ниже. Обратите внимание, что второй столбец заключен в кавычки , поэтому я ожидаю, что read_csv даст мне объект.

tmp.csv

0,1,2
"A","100",100
"B","200",200

1 Ответ

3 голосов
/ 10 июля 2019

Попробуйте использовать QUOTE_NONE вместо чтения, это сохранит типы данных между чтением / записью.

Использование исходного набора данных с int64:

import pandas as pd
from csv import QUOTE_NONNUMERIC, QUOTE_NONE
import sys

print('Python version information:')
print(sys.version)
print('Pandas version information:')
print(pd.__version__)

df1 = pd.DataFrame([['A', '100', 100], ['B', '200', 200]])
print('df1:')
print(df1.info())

df1.to_csv('tmp.csv', index=False, quoting=QUOTE_NONNUMERIC, quotechar='"')

df2 = pd.read_csv('tmp.csv', quoting=QUOTE_NONE).replace('"','', regex=True)
print('df2:')
print(df2.info())

Результат:

Python version information:
3.6.6 |Anaconda, Inc.| (default, Jun 28 2018, 11:27:44) [MSC v.1900 64 bit (AMD64)]
Pandas version information:
0.24.2
df1:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2 entries, 0 to 1
Data columns (total 3 columns):
0    2 non-null object
1    2 non-null object
2    2 non-null int64
dtypes: int64(1), object(2)
memory usage: 128.0+ bytes
None
df2:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2 entries, 0 to 1
Data columns (total 3 columns):
0    2 non-null object
1    2 non-null object
2    2 non-null int64
dtypes: int64(1), object(2)
memory usage: 128.0+ bytes
None

Использование float64 значений на входе:

import pandas as pd
from csv import QUOTE_NONNUMERIC, QUOTE_NONE, QUOTE_MINIMAL
import sys

print('Python version information:')
print(sys.version)
print('Pandas version information:')
print(pd.__version__)

df1 = pd.DataFrame([['A', '100', 100.1], ['B', '200', 200.2]])
print('df1:')
print(df1.info())

df1.to_csv('tmp.csv', index=False, quoting=QUOTE_NONNUMERIC, quotechar='"')

df2 = pd.read_csv('tmp.csv', quoting=QUOTE_NONE).replace('"','', regex=True)
print('df2:')
print(df2.info())

Результат:

Python version information:
3.6.6 |Anaconda, Inc.| (default, Jun 28 2018, 11:27:44) [MSC v.1900 64 bit (AMD64)]
Pandas version information:
0.24.2
df1:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2 entries, 0 to 1
Data columns (total 3 columns):
0    2 non-null object
1    2 non-null object
2    2 non-null float64
dtypes: float64(1), object(2)
memory usage: 128.0+ bytes
None
df2:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2 entries, 0 to 1
Data columns (total 3 columns):
0    2 non-null object
1    2 non-null object
2    2 non-null float64
dtypes: float64(1), object(2)
memory usage: 128.0+ bytes
None
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...