Предотвратить конечный нуль с пандами «to_csv»

Я пытаюсь экспортировать строку CSV в веб-приложение D3, но команда to_csv настаивает на добавлении завершающего 0 к данным, что препятствует правильному использованию D3.

Вот минимальный пример, иллюстрирующий проблему.

Мой (упрощенный) фрейм данных:

>>> df = pd.DataFrame([['Alex',20.0000, 50.650]],columns=['Name','Age', 'Weight'])
   Name   Age  Weight
0  Alex  20.0   50.65

df['Age'] содержит float, на что указывает:

>>> df['Age']
0    20.0
Name: Age, dtype: float64

Затем на основе этого отвечать я запускаю .astype(object), чтобы получить нужный формат:

>>> df=df.astype(object)
   Name Age Weight
0  Alex  20  50.65

Теперь df['Age'] содержит object без нуля в конце:

>>> df['Age']
0    20
Name: Age, dtype: object

Это то, что я хотел бы экспортировать с помощью to_csv, но эта команда повторно добавляет конечный 0 к числу, которого я хочу избежать:

>>> df_csv = df.to_csv(sep=',', index = False)
>>> df_csv
'Name,Age,Weight\nAlex,20.0,50.65\n'

Я пытался использовать df_csv = df.to_csv(sep=',', index = False, float_format='%.0f') на основе этот ответ, но это не работает, потому что в моем фрейме данных есть другие числа с плавающей запятой, для которых я хочу сохранить ненулевые десятичные числа.

Как я могу предотвратить появление этого конечного 0 для чисел без десятичных знаков?

Я должен отметить, что ответы кажутся неправильно отформатированными, возможно, потому, что d3.js является одним из тегов. Я пошел дальше и исправил форматирование всех.

xjcl 10.11.2020 16:35
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
4
1
4 396
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вы пробовали df['Age'] = df['Age'].astype(int)

это меня заводит

    Name    Age     Weight
0   Alex    20  50.65

преобразование столбца в тип object по существу позволяет столбцу содержать числа с плавающей запятой, целые числа, строки и т. д. по сравнению с типизированным столбцом, который будет содержать только этот тип.

И преобразовать его в csv:

df_csv = df.to_csv(sep=',', index = False)
    
'Name,Age,Weight\r\nAlex,20,50.65\r\n'

Спасибо, да, я пробовал это, но мне нужен "пакетный" подход, потому что есть сотни столбцов (некоторые из которых могут быть добавлены третьей стороной в будущем). Поэтому я бы предпочел избегать жесткого кодирования имен отдельных столбцов, что было преимуществом .astype(obj). Знаете ли вы, почему тип object эффективно удаляет конечный 0 в df, но не в результирующем csv?

sc28 28.05.2019 17:19

Вот один из способов, который будет работать, если у вас нет пробелов в столбцах строк.

Используйте to_string() после astype(object) вместо to_csv(). Это сохранит числовые форматы, но в качестве разделителя будут использоваться пробелы. Если у вас нет пробелов ни в одном из других полей, вы можете использовать регулярные выражения для преобразования пробелов в запятые.

import re
df = df.astype(object)
df_string = re.sub(" +", ",", df.to_string(index=False))
print(df_string)
#Name,Age,Weight
#Alex,20,50.65

Теперь напишите df_string в свой файл:

with open('path/to/some/file.csv', 'w') as f:
    f.write(df_string)
Ответ принят как подходящий

Другой способ использования Pandas replace :

df = df.astype(str)
df = df.replace(to_replace = "\.0+$",value = "", regex = True)

Таким образом, вам не нужно импортировать какой-либо дополнительный модуль.

Работает и со строками с пробелами.

pault 28.05.2019 18:01

На самом деле заменяемая строка должна быть "\.0+$", чтобы избежать изменения таких чисел, как 0.0286.

sc28 29.05.2019 19:36

Я действительно ненавижу это несоответствие между pandas.DataFrame.to_string и pandas.DataFrame.to_csv. Однако я спас данные, скопировав их в новый DataFrame с помощью applymap:

df_fixed = df.applymap(lambda cell: int(cell) if str(cell).endswith('.0') else cell)
>>> df.to_csv()
',Name,Age,Weight\n0,Alex,20.0,50.65\n'

>>> df_fixed.to_csv()
',Name,Age,Weight\n0,Alex,20,50.65\n'

Обратите внимание, что это не работает с большими числами (например, 10 ** 7), потому что оно начнет использовать нотацию e (1e7).

Другие вопросы по теме