Python pandas: выводит фрейм данных в csv с целыми числами

у меня естьpandas.DataFrame что я хочу экспортировать в файл CSV. Тем не менее, панды, кажется, пишут некоторые значения какfloat вместоint типы. Я не могНе могу найти, как изменить это поведение.

Создание фрейма данных:

df = pandas.DataFrame(columns=['a','b','c','d'], index=['x','y','z'], dtype=int)
x = pandas.Series([10,10,10], index=['a','b','d'], dtype=int)
y = pandas.Series([1,5,2,3], index=['a','b','c','d'], dtype=int)
z = pandas.Series([1,2,3,4], index=['a','b','c','d'], dtype=int)
df.loc['x']=x; df.loc['y']=y; df.loc['z']=z

Посмотреть это:

>>> df
    a   b    c   d
x  10  10  NaN  10
y   1   5    2   3
z   1   2    3   4

Экспортируйте это:

>>> df.to_csv('test.csv', sep='\t', na_rep='0', dtype=int)
>>> for l in open('test.csv'): print l.strip('\n')
        a       b       c       d
x       10.0    10.0    0       10.0
y       1       5       2       3
z       1       2       3       4

Почему десятки имеют точку ноль?

Конечно, я мог бы просто вставить эту функцию в свой конвейер, чтобы преобразовать весь файл CSV, но это кажется ненужным:

def lines_as_integer(path):
    handle = open(path)
    yield handle.next()
    for line in handle:
        line = line.split()
        label = line[0]
        values = map(float, line[1:])
        values = map(int, values)
        yield label + '\t' + '\t'.join(map(str,values)) + '\n'
handle = open(path_table_int, 'w')
handle.writelines(lines_as_integer(path_table_float))
handle.close()
 xApple18 нояб. 2015 г., 17:31
@AndyHayden Дольше печатать, но определенно легче читать. Новичку, спотыкающемуся в коде,pd означает Департамент полиции. Или хуже, если он говорит по-французски.
 xApple22 сент. 2015 г., 17:08
@ Энди, почему я должен это делать? Пространства имен - отличная идея ... пока вы не сокращаете их все, и это становится нечитаемым.
 Andy Hayden22 сент. 2015 г., 19:13
Тот's стандарт, numpy также np (и доступен как pd.np). pandas значительно длиннее pd, каждый раз записывая его, вы создадите кодМеньше читаемый ИМО.
 Andy Hayden13 июн. 2013 г., 18:52
вам следуетimport pandas as pd :)
 xApple24 февр. 2019 г., 16:51
Я неЯ думаю, что аналогия адекватна, потому что движение слева несовместимо с движением справа. Однако использование полного имени пакета прекрасно работает для ветерана, который знает о стандарте аббревиатур, в то время как обратное неверно (новичок сбит с толкуpd).
 Thomas Kimber01 нояб. 2016 г., 18:11
Это'Это просто соглашение - используйте его или неt использовать его - зависит от того, кем будет ваша аудитория. - Для многих пользователей панд принято использовать pd, так же как и в Великобритании, конвенция заключается в движении слева. Это'Это не проблема, пока вы не пройдете тот же участок дороги.

Ответы на вопрос(5)

Решение Вопроса

который я искал, был небольшим изменением того, что @Jeff предложил в своем ответе. Кредит идет к нему. Это то, что решило мою проблему в конце для справки:

    import pandas
    df = pandas.DataFrame(data, columns=['a','b','c','d'], index=['x','y','z'])
    df = df.fillna(0)
    df = df.astype(int)
    df.to_csv('test.csv', sep='\t')
 Sigur14 дек. 2018 г., 17:18
Как это сделать только для одного столбца? мойdf имеет смешанные типы, строки и числа.
 Tad19 авг. 2018 г., 21:14
Вы можете сослаться на мой ответ ниже, чтобы сохранить NaN
 laviex06 мар. 2019 г., 22:52
если ваши данные натуральные числа (неотрицательные целые числа), используяdf.fillna(-1) это вариант.
 Cyrille02 сент. 2015 г., 00:56
Это обходится при наличии любых поплавков, но вы теряете информацию о NaN. Возможно, заполните NA значением -9999 или каким-то другим значением, которое, как вы знаете, не являетсяреальный» в вашем наборе данных.

чтобы указать тип данных для каждого столбца

Например:

import pandas
df = pandas.DataFrame(data, columns=['a','b','c','d'], index=['x','y','z'])

df = df.astype({"a": int, "b": complex, "c" : float, "d" : int})

Проблема в том, что, поскольку вы назначаете вещи по строкам, а dtypes группируются по столбцам, то естьobject dtype, что не очень хорошо, вы теряете всю эффективность. Таким образом, один из способов - конвертировать, который будет приводить к типу float / int по мере необходимости.

Как мы ответили в другом вопросе, если вы строите фрейм сразу (или строите столбец за столбцом), этот шаг не понадобится

In [23]: def convert(x):
   ....:     try:
   ....:         return x.astype(int)
   ....:     except:
   ....:         return x
   ....:     

In [24]: df.apply(convert)
Out[24]: 
    a   b   c   d
x  10  10 NaN  10
y   1   5   2   3
z   1   2   3   4

In [25]: df.apply(convert).dtypes
Out[25]: 
a      int64
b      int64
c    float64
d      int64
dtype: object

In [26]: df.apply(convert).to_csv('test.csv')

In [27]: !cat test.csv
,a,b,c,d
x,10,10,,10
y,1,5,2.0,3
z,1,2,3.0,4
 Andy Hayden13 июн. 2013 г., 19:30
Но, но ..., если вы используете dtype = object (например, в x и df через OP 'с конструкцией, которая, я согласен, не лучший способ) тогда 2, 3 и 10 - это целые числа ... это 'С почти всегда не стоит беспокоиться. Это похоже на транспонирование OP 'с усилием: с
 xApple13 июн. 2013 г., 20:55
я счастлив иметь нули вместо NaN. Могу ли я получить производительность и удобство, избегаяdtype=object и используя некоторую комбинациюdf.fillna(value=0) и преобразование обратно в целые числа?
 Andy Hayden13 июн. 2013 г., 19:08
Но тогда есть.0вc столбцы ...: s
 Andy Hayden13 июн. 2013 г., 20:38
Если они изо всех силвыбирать dtype = object, хотя, безусловно, они заслуживают того, что получают (если нет онипоплавок). Лучшим решением для numy будет поддержка NaN в целочисленных массивах ...;) I '
 Jeff13 июн. 2013 г., 19:26
потому что это поплавок! Там нет выбора (хорошо, вы можете пройтиfloat_format='%.0f' вto_csv но это может привести к потере точности -
 xApple14 июн. 2013 г., 11:44
Мне нужны целые числа, потому что этот CSV-файл экспортируется для чтения другим компонентом в дальнейшем. Этот другой компонент был написан давно кем-то на другом языке и неМне нравится иметь поплавки в качестве входных данных.
 Jeff14 июн. 2013 г., 14:29
затемconvert_objects().fillna(0).astype(int).to_csv(path) должен работать на вас
 Jeff13 июн. 2013 г., 19:50
да ... продолжайте подчеркивать, что имеяobject dtype для чисел - это плохо .... может быть, мы должны поместить в PerformanceWarning, если это произойдет (например, как в этом случае) ....
 Jeff13 июн. 2013 г., 21:01
если вы хотите заполнить, как вы заполняете, проверьтеdf.dtypes; ты можешь сделатьdf.convert_objects() чтобы автоматически конвертировать в поплавки скорее всего, тогда вы можетеastype если ты хочешь. Вы можетеfillna если ты действительно хочешь. Вопрос в том, почему это важно? (remmeber вы всегда можете указать dtypes сread_csv) и почему тынеобходимость целые числа?

Если вы хотите сохранить информацию NaN в экспортированном CSV-файле, выполните следующие действия. П.С .: Я 'м, концентрируясь на столбце «С» в этом случае.

df[c] = df[c].fillna('')       #filling Nan with empty string
df[c] = df[c].astype(str)      #convert the column to string 
>>> df
    a   b    c     d
x  10  10         10
y   1   5    2.0   3
z   1   2    3.0   4

df[c] = df[c].str.split('.')   #split the float value into list based on '.'
>>> df
        a   b    c          d
    x  10  10   ['']       10
    y   1   5   ['2','0']   3
    z   1   2   ['3','0']   4

df[c] = df[c].str[0]            #select 1st element from the list
>>> df
    a   b    c   d
x  10  10       10
y   1   5    2   3
z   1   2    3   4

Теперь, если вы экспортируете фрейм данных в csv, столбец 'c' не будет иметь значения с плавающей запятой и информация NaN сохраняется.

 xApple24 февр. 2019 г., 16:54
Это хорошее решение, но оно предполагает, что вы знаете, в каком столбце отсутствуют данные, что редко встречается.

Попался" в пандах (поддержка целых чисел NA)где целочисленные столбцы с NaN конвертируются в числа с плавающей точкой.

Этот компромисс сделан в основном из-за памяти и производительности, а также из-за того, что полученная серия продолжает оставаться «числовой», Одна из возможностей заключается в использованииdtype=object вместо массивов.

 xApple13 июн. 2013 г., 18:55
Так нет ли способа получить их как целые числа без повторного анализа всего файла? Как насчет того, если я использую?df.fillna()
 Andy Hayden13 июн. 2013 г., 19:00
использованиеdtype=object (скорее, чемint) при созданииx а также .df

Ваш ответ на вопрос