【问题标题】:Converting string column from DataFrame to float for .sum()将字符串列从 DataFrame 转换为 .sum() 的浮点数
【发布时间】:2021-11-16 23:51:52
【问题描述】:

我有一个如下的DataFrame:

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

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

我需要 DataFrame 像这样结束:

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

我尝试做的是:

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

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

注意:为了更好地理解,这些值带有“+”,但我需要的结果是 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 万行。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    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
    

    【讨论】:

    • 我可以使用 df['A'] 吗?因为 A 字符串实际上是 ' A '。
    • @AntonioLópezRuiz 是的!
    • 我收到以下错误:ValueError: Unable to parse string
    • @AntonioLópezRuiz 我只是在更新答案,提供有关如何处理的信息。
    • @AntonioLópezRuiz 检查我最近的更新,因为这可能对你更有用。
    【解决方案2】:

    取决于你的目标:

    In [65]: x.groupby(['A','B'])['C'].apply(lambda c: c.str.strip().str.cat(sep='+')).reset_index()
    Out[65]:
       A  B      C
    0  a  d  1.1+2
    1  a  e    1+3
    2  c  f    3.2
    

    或计算总和:

    In [64]: x.groupby(['A','B'])['C'].apply(lambda c: pd.eval(c.str.cat(sep='+'))).reset_index()
    Out[64]:
       A  B    C
    0  a  d  3.1
    1  a  e  4.0
    2  c  f  3.2
    

    【讨论】:

      【解决方案3】:

      编辑:首先替换 C 列中的逗号

      df.C = df.C.str.replace(',', '')
      df.C = df.C.astype(np.float)
      df.groupby(['A','B']).C.sum().reset_index()
      

      我将最后一行的值更改为“1,994,102”。你得到

          A   B   C
      0   a   d   3.1
      1   a   e   4.0
      2   c   f   1994102.0
      

      【讨论】:

      • 这正是我试图做的,但是我得到以下错误:** 无法将字符串转换为浮点数:'1,994,102' **
      【解决方案4】:

      你可以使用简单的一行代码:

      df.groupby(['A','B']).agg(lambda x : sum(x.astype(float)))

      给定数据框的结果将是 -

             C
      A B     
      a d  3.1
        e  4.0
      c f  3.2
      

      【讨论】:

        猜你喜欢
        • 2013-05-19
        • 2011-11-25
        • 1970-01-01
        • 2021-07-22
        • 1970-01-01
        • 2014-09-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多