我将关于欧盟的邮件红色转换为美国小数点转换,这些帮助很多,但我还是觉得需要专家的帮助。我的数据来自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(和磁盘..)所以愿意直接在DataFrame上尝试.replace方法来节省一些处理时间。
我最初的尝试是类似下面的内容(我在论坛上的其他地方红了......):
result['column_name'] = result['column_name'].replace( '.', '')
result['column_name'] = result['column_name'].replace( ',', '.')
result['column_name'] = result['column_name'].astype(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)
上面的工作......虽然有些意外,它看起来比read_csv / converter解决方案慢了约3倍。使用以下内容有所帮助:
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已经过优化..但是并没有真正期望红色/写/读/写cicle比for循环快三倍!!
你认为在这方面做更多工作可能值得吗?有什么建议吗?或者继续使用重复的写/读/写方法更好?
我的文件大约是30k行x 150列,读/写/读(转换)/写大约需要18秒,.ix for大于52秒,第一种循环(32和分组.replace) )。
您将DataFrames从欧盟格式转换为美国格式有何经验?一些建议的改进方法?怎么样'映射'或者' locale' ?他们可能会更快吗?
非常感谢Fabio。
P.S。我意识到自己很啰嗦'并没有想到' pythonic'对不起抱歉..我还在学习......: - )
答案 0 :(得分:2)
实际上read_csv中有一个千位和十进制参数 (见pandas documentation read_csv 但不幸的是,两者还没有合作(见问题:github issue)
答案 1 :(得分:1)
非常感谢你给我的建议和帮助,安迪和杰夫!你帮了很多忙: - )
我首先带着编辑回到原始数据。在其中一些我看到系统可能应用了某种自动转换,所以我新下载了与'未转换'选项相同的数据集,并避免使用例如Excel或其他程序来打开/保存文件。我只使用文本编辑器。在这一点上,我使read_csv更轻,没有转换器,并按照Jeff的建议对替换进行分组。
真实情况比提供的示例稍长,包括一些剥离(空格),列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_csv中跳过'转换器'的代码中删除。
感谢您的帮助:-)!
再见。再见。法比奥。答案 2 :(得分:0)
使用您指定的值创建一个框架并写入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
总时间低于6s
仅供参考,有一个thousands
单独选项,但不是decimal
一个....嗯这会快得多......