Подтвердить что ты не робот

Pandas чтение csv как тип строки

У меня есть фрейм данных с буквенно-цифровыми клавишами, которые я хочу сохранить как csv и прочитать позже. По разным причинам мне нужно явно прочитать этот ключевой столбец как строковый формат, у меня есть ключи, которые являются строго цифровыми или даже хуже, такими как: 1234E5, который Pandas интерпретирует как float. Это, очевидно, делает ключ совершенно бесполезным.

Проблема в том, что когда я указываю строку dtype для фрейма данных или любого столбца, я просто возвращаю мусор. У меня есть пример кода здесь:

df = pd.DataFrame(np.random.rand(2,2),
                  index=['1A', '1B'],
                  columns=['A', 'B'])
df.to_csv(savefile)

Кадр данных выглядит так:

           A         B
1A  0.209059  0.275554
1B  0.742666  0.721165

Затем я прочитал его так:

df_read = pd.read_csv(savefile, dtype=str, index_col=0)

и результат:

   A  B
B  (  <

Это проблема с моим компьютером или что-то, что я делаю неправильно здесь, или просто ошибка?

4b9b3361

Ответ 1

Обновление: это было исправлено: начиная с 0.11.1 передача вами str/np.str будет эквивалентна использованию object.

Используйте объект dtype:

In [11]: pd.read_csv('a', dtype=object, index_col=0)
Out[11]:
                      A                     B
1A  0.35633069074776547     0.745585398803751
1B  0.20037376323337375  0.013921830784260236

или еще лучше, просто не указывайте dtype:

In [12]: pd.read_csv('a', index_col=0)
Out[12]:
           A         B
1A  0.356331  0.745585
1B  0.200374  0.013922

но обход обхода типа и действительно возвращение только строк требует хакерского использования converters:

In [13]: pd.read_csv('a', converters={i: str for i in range(100)})
Out[13]:
                      A                     B
1A  0.35633069074776547     0.745585398803751
1B  0.20037376323337375  0.013921830784260236

где 100 - это число, равное или превышающее общее количество столбцов.

Лучше всего избегать str dtype, см., Например, здесь.

Ответ 2

Как сказал Антон Т в своем комментарии, pandas будет случайным образом преобразовывать типы object в типы с float используя его сниффер типов, даже если вы передадите dtype=object, dtype=str или dtype=np.str.

Поскольку вы можете передать словарь функций, где ключ - это индекс столбца, а значение - это функция преобразователя, вы можете сделать что-то подобное (например, для 100 столбцов).

pd.read_csv('some_file.csv', converters={i: str for i in range(0, 100)})

Вы даже можете передать range(0, N) для N, который намного больше, чем количество столбцов, если вы не знаете, сколько столбцов вы будете читать.

Ответ 3

Используйте конвертер, который применяется к любому столбцу, если вы не знаете столбцы заранее:

import pandas as pd

class StringConverter(dict):
    def __contains__(self, item):
        return True

    def __getitem__(self, item):
        return str

    def get(self, default=None):
        return str

pd.read_csv(file_or_buffer, converters=StringConverter())