Skip to main content
 首页 » 编程设计

python之将字符串列从 DataFrame 转换为 float for .sum()

2025年05月04日11lhb25

我有一个 DataFrame 如下:

A   B   C 
a   d  '1.1' 
a   d  ' 2 ' 
a   e  '1' 
a   e  ' 3 '  
c   f  '3.2 ' 

我需要的是对 C 列的值求和,同时将它们与 A 和 B 分组。但是,这些值是字符串而不是 float ,有些有空格,有些没有。

我需要 DataFrame 像这样结束:

A  B  C 
a  d  1.1+2 
a  e  1+3 
c  f  3.2 

我尝试做的是:

df.groupby(['A','B']).sum()

然而,由于它们是字符串,它只是将它们合并在一起,并没有真正对它们求和。之后,我尝试将它们转换为 float ,但由于空格不允许我这样做。最后,我试图删除字符串,但它说它不能对某些元素进行操作,因为它们是整数 (??)。我猜后者是因为它没有空格。

注意:为了更好理解,这些值带有“+”,但我需要的结果是 3.1、4 和 3.2

我的显式 csv 是这样的:

DL_INSTITUCION,PERIODO_QUE_SE_REPORTA, RESPONSABILIDAD_TOTAL  
Santander,201412,"92,467" 
Banca Mifel,201412," 39,089 " 
Banca Mifel,201412," 28,286 " 
Banca Mifel,201412," 310,902 " 
CIBanco,201412," 10,106 " 
CIBanco,201412," 46,872 " 
Banorte/Ixe,201412," 3,127,120 " 
CIBanco,201412," 10,163 " 
Santander,201412," 545,027 " 
Banca Mifel,201412," 10,291 " 
Banca Mifel,201412," 80,738 " 
Banca Mifel,201412," 46,329 " 
HSBC,201412," 583,274 " 
CIBanco,201412," 24,094 " 

虽然是 2800 万行。

请您参考如下方法:

使用 pd.to_numeric 很简单
此解决方案的优点是使用 pd.to_numeric
简洁高效 这是有效的,因为如果将 pd.Series 对象传递给它,pd.to_numeric 会返回一个带有索引的 pd.Series 对象。这为我们提供了将结果轻松传输到 groupby 所需的便利。

pd.to_numeric(df.C).groupby([df.A, df.B]).sum() 
 
A  B 
a  d    3.1 
   e    4.0 
c  f    3.2 
Name: C, dtype: float64 

errors='coerce'
还有一个额外的好处是,如果我们需要处理不能解析为 float 的字符串,我们可以使用参数 errors='coerce'。这会将不可解析的字符串强制为 np.nan,并且仍然允许有用的聚合。

pd.to_numeric(df.C, errors='coerce').groupby([df.A, df.B]).sum() 

处理逗号

pd.to_numeric(df.C.str.replace(',', ''), 'coerce').groupby([df.A, df.B]).sum() 

设置

df = pd.DataFrame(dict( 
        A=list('aaaac'), 
        B=list('ddeef'), 
        C='1.1| 2 |1| 3 |3.2 '.split('|') 
    )) 

您可以使用 pd.read_csv 解决其中的许多问题

from io import StringIO 
import pandas as pd 
 
txt = """DL_INSTITUCION,PERIODO_QUE_SE_REPORTA, RESPONSABILIDAD_TOTAL  
Santander,201412,"92,467" 
Banca Mifel,201412," 39,089 " 
Banca Mifel,201412," 28,286 " 
Banca Mifel,201412," 310,902 " 
CIBanco,201412," 10,106 " 
CIBanco,201412," 46,872 " 
Banorte/Ixe,201412," 3,127,120 " 
CIBanco,201412," 10,163 " 
Santander,201412," 545,027 " 
Banca Mifel,201412," 10,291 " 
Banca Mifel,201412," 80,738 " 
Banca Mifel,201412," 46,329 " 
HSBC,201412," 583,274 " 
CIBanco,201412," 24,094 " 
""" 
 
df = pd.read_csv(StringIO(txt), skipinitialspace=True, thousands=',') 

您现在会注意到 dtypes 已被正确推断

df.dtypes 
 
DL_INSTITUCION            object 
PERIODO_QUE_SE_REPORTA     int64 
RESPONSABILIDAD_TOTAL      int64 
dtype: object 

我们可以毫无问题地进行聚合。

df.groupby(['DL_INSTITUCION', 'PERIODO_QUE_SE_REPORTA']).sum() 
 
                                       RESPONSABILIDAD_TOTAL  
DL_INSTITUCION PERIODO_QUE_SE_REPORTA                         
Banca Mifel    201412                                  515635 
Banorte/Ixe    201412                                 3127120 
CIBanco        201412                                   91235 
HSBC           201412                                  583274 
Santander      201412                                  637494