Python Pandas 十进制标记欧盟到美国

问题描述 投票:0回答:4

我红色了有关欧盟到美国十进制标记转换的邮件,这些帮助很大,但我仍然觉得需要专家的一些帮助..我的数据来自 ERP 系统,其数字格式为“1'000” '000,32”,我想简单地转换成“1000000.32”之类的东西,以便在 Pandas 中进一步处理。

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

... 
 # 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/converters 解决方案慢了大约 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 秒(分组 .replace 的时间为 32 秒)。

您将 DataFrame 从欧盟格式转换为美国格式的经验是什么?一些建议的改进方法? “映射”或“区域设置”怎么样?他们可能会更快吗?

非常感谢你,法比奥。

附注我意识到我很“冗长”并且不够“Pythonic”..抱歉抱歉..我还在学习......:-)

pandas decimal
4个回答
2
投票

非常感谢安迪和杰夫的建议和帮助!你帮了很多忙:-)

我首先与编辑一起返回原始数据。在其中一些中,我看到系统可能应用了某种自动转换,因此我新下载了相同的数据集作为“未转换”选项,并避免使用例如Excel 或其他打开/保存文件的程序。我只使用文本编辑器。此时,我使 read_csv 变得更轻,没有转换器,并按照 Jeff 的建议对替换进行了分组。

真实案例比提供的示例稍长一些,包括一些剥离(空格)、列删除、字符串连接、重命名/替换...。小数点被替换为三列: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 秒:-) :-) 包括我在这里没有详细说明的所有其他内容(剥离、删除、连接,..)。所有读/写/读/写都已从代码中删除,在 read_csv 期间跳过“转换器”。

感谢您的帮助:-)!

再见。法比奥。

    -

1
投票

其实read_csv中有一个千位和小数的参数 (参见 pandas 文档 read_csv 但不幸的是,两者还不能一起工作(参见问题:github问题


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

总时间小于6秒

仅供参考,有一个

thousands
单独的选项,但没有
decimal
选项....嗯,这会快得多....


0
投票

解决此问题的另一种方法:

def convert_to_US(col):
   df[col] = df[col].str.replace(',', '.').astype(float)

cols = ['A','B','C']
for col in cols: convert_to_US(col)
© www.soinside.com 2019 - 2024. All rights reserved.