首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python Pandas Decimal Mark EU to US

Python Pandas Decimal Mark EU to US
EN

Stack Overflow用户
提问于 2013-07-09 00:14:24
回答 3查看 5.1K关注 0票数 2

我查看了有关欧盟到美国小数转换的邮件,这些帮助很大,但我仍然觉得需要一些专家的帮助。我的数据来自ERP系统,其格式类似于"1'000'000,32“,我想简单地将其转换为类似"1000000.32”的格式,以便在Pandas中进一步处理。

我从欧盟开始获取美国格式的实际解决方案如下:

代码语言:javascript
复制
... 
 # 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 (以及磁盘..)因此愿意在DataFrame上直接尝试.replace方法,以节省一些处理时间。

我最初的想法是这样的(我在论坛的其他地方写了):

代码语言:javascript
复制
result['column_name'] = result['column_name'].replace( '.', '')
result['column_name'] = result['column_name'].replace( ',', '.')
result['column_name'] =  result['column_name'].astype(float)

这不起作用,并导致“浮点数的无效文本”错误。

因此,我移动到:

代码语言:javascript
复制
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)

上面的方法起作用了。但令人惊讶的是,它似乎比read_csv/converters解决方案慢了大约3倍。以下代码的使用在某种程度上有所帮助:

代码语言:javascript
复制
    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循环快三倍!

你觉得在这个案子上多花点功夫值得吗?有什么建议吗?还是继续使用重复的写/读/写方法更好?

我的文件超过30k行x 150列,读/写/读(转换)/write大约需要18秒,使用第一种循环的.ix在52秒以上(使用分组的.replace使用32秒)。

您在将DataFrames从欧盟格式转换为美国格式的过程中有什么经验?有什么建议的改进方法吗?“映射”或“区域设置”又如何呢?它们会不会更快?

非常感谢你,法比奥。

附言:我意识到我太“罗嗦”了,而且还不够“蟒蛇”。对不起对不起..。我还在学习...:-)

EN

回答 3

Stack Overflow用户

发布于 2013-07-09 22:24:49

非常感谢你们的建议和帮助,Andy和Jeff!你帮了很大的忙:-)

我首先和一位编辑回到了原始数据。在其中一些文件中,我看到系统可能应用了某种自动转换,所以我新下载了与“未转换”选项相同的数据集,并避免使用Excel或其他程序打开/保存文件。我只使用了文本编辑器。在这一点上,我使read_csv更轻,没有转换器,并按照杰夫的建议对替换项进行了分组。

实际情况比提供的示例要长一点,其中包括一些剥离(空格)、列del、字符串连接、重命名/替换...小数标记被替换为三列:美元销售额,数量,USD_EUR汇率。在此基础上,计算欧元销售额和欧元单价。在初始文件中,由于某些其他原因,我们在要固定的汇率之前还有一个'-‘("-","")。结果是:

代码语言:javascript
复制
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秒:-) :-)包括我在这里没有详细介绍的所有其他内容(剥离、删除、连接、..)。所有读/写/读/写操作都已从代码中删除,在read_csv期间跳过了“转换器”。

感谢您的帮助:-)!

拜拜。法比奥。

代码语言:javascript
复制
-
票数 2
EN

Stack Overflow用户

发布于 2013-07-20 03:18:27

事实上,read_csv中有一个千和小数参数(参见pandas documentation read_csv,但遗憾的是两者还不能一起使用(参见问题:github issue))

票数 1
EN

Stack Overflow用户

发布于 2013-07-09 07:58:28

使用指定的值创建帧并将其写入csv

代码语言:javascript
复制
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')

读入,没有转换器

代码语言:javascript
复制
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(.....)来指定某些列

代码语言:javascript
复制
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 one....hmmm这会快得多……

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17531313

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档