Питон Панды Десятичный знак ЕС в США

Я переписывал письма о преобразовании десятичных знаков в ЕС и США, это очень помогло, но я все еще чувствую, что мне нужна помощь экспертов. Мои данные взяты из системы ERP с числами в формате, подобном "1'000" 000,32", и я хотел бы просто преобразовать во что-то вроде"1000000.32"для дальнейшей обработки в Пандах.

Мое реальное решение получить формат США, начиная с ЕС, выглядит следующим образом:

... 
 # read_csv and merge, clean .. different CSV files
 # result = merge (some_DataFrame_EU_format, ...)
...
result.to_csv(path, sep';')
result = read_csv(path, sep';', converters={'column_name': lambda x: float(x.replace   ('.','').replace(',','.'))})
....
result.to_csv(path, sep';')

У меня было чувство, что это медленный способ изменить "," на "." из-за read_csv и to_csv (и диска..) он был готов попробовать метод.replace непосредственно в DataFrame, чтобы сэкономить время обработки.

Моим первоначальным предположением было что-то вроде ниже (что я красный в другом месте здесь на форуме..):

result['column_name'] = result['column_name'].replace( '.', '')
result['column_name'] = result['column_name'].replace( ',', '.')
result['column_name'] =  result['column_name'].astype(float)

Что не сработало и привело к ошибке "Недопустимый литерал для float".

Я так переехал в:

for i in range (0, len(result)):
    result.ix[i,'column_name'] = result.ix[i,'column_name'].replace( '.', '')
    result.ix[i,'column_name'] = result.ix[i,'column_name'].replace( ',', '.')
result['column_name'] =  result['column_name'].astype(float)

Вышеописанное сработало... но с некоторым удивлением оно оказалось примерно в 3 раза медленнее, чем решение read_csv/convertters. Использование ниже помогло в некотором роде:

    for i in range (0, len(result)):
    result.ix[i,'column_name'] = result.ix[i,'column_name'].replace( '.', '').replace( ',', '.')
    result['column_name'] =  result['column_name'].astype(float)

Я прочитал прекрасные руководства... и знаю, что read_csv оптимизирован... но на самом деле не ожидал, что красный цикл / запись / чтение / запись будет в три раза быстрее цикла for!!

Как вы думаете, может быть стоит поработать над этим больше? Любое предложение? Или лучше остаться с повторным подходом записи / чтения / записи?

Мой файл составляет около 30 тыс. Строк по 150 столбцов, чтение / запись / чтение (преобразование)/ запись занимает около 18 секунд,.ix для более 52 секунд с циклом первого типа (и 32 с сгруппированным.replace).

Каков ваш опыт конвертации DataFrames из формата EU в США? Какой-то предложенный способ улучшить? Что насчет "картографирования" или "локали"? Могут ли они быть быстрее?

Большое спасибо, Фабио.

PS Я понимаю, что я был "многословен" и не достаточно "питоничен".. извините извините.. я все еще учусь...:-)

3 ответа

На самом деле в read_csv есть тысячи и десятичный параметр (см. Документацию pandas read_csv, но, к сожалению, оба они не работают вместе (см. Проблему: проблема с github)

Огромное спасибо за ваши замечательные предложения и помощь, Энди и Джефф! Вы очень помогли:-)

Сначала я вернулся с редактором к исходным данным. В некоторых из них я видел, что система, вероятно, применила какое-то автоматическое преобразование, поэтому я недавно загрузил тот же набор данных, что и опция "без преобразования", и избегал использовать, например, Excel или другие программы для открытия / сохранения файлов. Я использовал только текстовые редакторы. В этот момент я сделал read_csv более легким без конвертеров и сгруппировал замены, как предложил Джефф.

Реальный регистр немного длиннее, чем приведенный пример, и включает некоторые чередование (пробелы), столбцы del, concat строки, переименование / замену.... Десятичные знаки заменяются на три столбца: USD Sales, Qty, USD_EUR. На их основе рассчитываются продажи в евро и единичные цены в евро. В исходном файле у нас также есть "-", по какой-то другой причине, до того, как обменный курс будет установлен ("-", ""). Результат:

result = pd.read_csv(path, sep=';', thousands = '.')
col = [ 'qty', 'sales', 'rate']
result[col] = result[col].apply(lambda x: x.str.replace(".","").str.replace(",","."))
result['sales_localcurrency'] = abs(result['sales'].astype(float) / result['rate'].astype(float))
result['sales_localcurrency_unit'] = result['sales_localcurrency'] / result['qty'].astype(float)
result.to_csv(path, sep=';')

30 000 x 150 DataFrame обрабатывается менее чем за 15 секунд:-):-), включая все остальные вещи, которые я здесь подробно не описывал (разбор, del, concat, ..). Все что read/write/read/write было удалено из кода, пропуская "конвертеры" во время read_csv.

Спасибо за вашу помощь:-)!

Пока-пока. Фабио.

    -

Создайте фрейм со значением, которое вы указали, и запишите в CSV

In [2]: df = DataFrame("100'100,32",index=range(30000),columns=range(150))

In [3]: df.iloc[0:5,0:5]
Out[3]: 
            0           1           2           3           4
0  100'100,32  100'100,32  100'100,32  100'100,32  100'100,32
1  100'100,32  100'100,32  100'100,32  100'100,32  100'100,32
2  100'100,32  100'100,32  100'100,32  100'100,32  100'100,32
3  100'100,32  100'100,32  100'100,32  100'100,32  100'100,32
4  100'100,32  100'100,32  100'100,32  100'100,32  100'100,32

In [4]: df.to_csv('test.csv')

Прочитайте это, нет конвертеров

In [5]: df = read_csv('../test.csv',index_col=0)

In [6]: %timeit read_csv('../test.csv',index_col=0)
1 loops, best of 3: 1e+03 ms per loop

In [7]: df
Out[7]: 
<class 'pandas.core.frame.DataFrame'>
Int64Index: 30000 entries, 0 to 29999
Columns: 150 entries, 0 to 149
dtypes: object(150)

In [8]: %timeit read_csv('../test.csv',index_col=0)
1 loops, best of 3: 1e+03 ms per loop

Делать подстановку строк столбец за столбцом. Здесь вы можете указать только определенные столбцы, если хотите, выполнив df[[ list of columns ]].apply(.....)

In [9]: df.apply(lambda x: x.str.replace("'","").str.replace(",",".")).astype(float)
Out[9]: 
<class 'pandas.core.frame.DataFrame'>
Int64Index: 30000 entries, 0 to 29999
Columns: 150 entries, 0 to 149
dtypes: float64(150)

In [10]: %timeit df.apply(lambda x: x.str.replace("'","").str.replace(",",".")).astype(float)
1 loops, best of 3: 4.77 s per loop

Общее время тени до 6 с

К вашему сведению, есть thousands отдельный вариант, но не decimal один.... хм это было бы намного быстрее....

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