【问题标题】:Convert number strings with commas in pandas DataFrame to float将pandas DataFrame中带逗号的数字字符串转换为浮点数
【发布时间】:2020-04-21 23:30:00
【问题描述】:

我有一个 DataFrame,其中包含作为千位标记的逗号字符串形式的数字。我需要将它们转换为浮点数。

a = [['1,200', '4,200'], ['7,000', '-0.03'], [ '5', '0']]
df=pandas.DataFrame(a)

我猜我需要使用 locale.atof。确实

df[0].apply(locale.atof)

按预期工作。我得到了一系列的花车。

但是当我将它应用到 DataFrame 时,我得到了一个错误。

df.apply(locale.atof)

TypeError: ("cannot convert the series to ", u'occurred at index 0')

df[0:1].apply(locale.atof)

给出另一个错误:

ValueError: ('invalid literal for float(): 1,200', u'occurred at index 0')

那么,如何将这个 DataFrame 字符串转换为浮点数据帧?

【问题讨论】:

  • 老问题,但 OP 收到该错误,因为 DataFrame 上的 apply 将整个 column 作为一个系列传递给函数(在本例中为 locale.atof,它需要一个字符串)。如果您使用@AndyHayden 在下面的答案中所做的applymap 方法,您应该可以做到这一点。

标签: python pandas


【解决方案1】:

如果您是reading in from csv,那么您可以使用thousands arg

df.read_csv('foo.tsv', sep='\t', thousands=',')

这种方法可能比单独执行操作更有效。


你需要先set the locale

In [ 9]: import locale

In [10]: from locale import atof

In [11]: locale.setlocale(locale.LC_NUMERIC, '')
Out[11]: 'en_GB.UTF-8'

In [12]: df.applymap(atof)
Out[12]:
      0        1
0  1200  4200.00
1  7000    -0.03
2     5     0.00

【讨论】:

  • 我应该说我确实设置了语言环境。我仍然得到错误。
  • 但是我正在使用 df.read_fwf,并且它也有“数千=','”选项,它可以工作。谢谢。
  • 那么,为什么 df.applymap(atof) 对你有用,但对我没有用?我的语言环境是“en_US.UTF-8”。
  • 我投票支持 read_csv 函数的“千”参数提示。这对我很有用。
  • 我想补充一点,如果您正在处理浮点数,您也可以使用“decimal=','”。
【解决方案2】:

您可以使用pandas.Series.str.replace 方法:

df.iloc[:,:].str.replace(',', '').astype(float)

此方法可以删除或替换字符串中的逗号。

【讨论】:

  • 我收到“AttributeError: 'DataFrame' object has no attribute 'str'”,不知道为什么...
  • 但这有效:df.apply(lambda x: x.str.replace(',', '').astype(float), axis=1)
  • 如果我的号码有多个逗号怎么办?如:“1,099,99”,如何将其转换为“'1099.99'”?
【解决方案3】:

您可以像这样一次转换一列:

df['colname'] = df['colname'].str.replace(',', '').astype(float)

【讨论】:

  • 这样,我得到一个警告:FutureWarning:在未来的版本中,正则表达式的默认值将从 True 更改为 False。此外,当 regex=True 时,单字符正则表达式将被视为文字字符串。不知道为什么它假定 regex=True
  • 这是一个可怕的想法。它将0,2 转换为2 而不是0.2。根本没有办法使用替换来解析本地化的数字文字。 10,000.0 呢? 10.000,00 呢?
  • 谢谢你,@PanagiotisKanavos。您的评论使我无法陷入这个重大陷阱并继续处理严重混乱的数据。 pd.Series('0,5').str.replace(',', '').astype(float) 返回 5!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多