【问题标题】:How to sum a dataframe column of lists of numbers in string form?如何以字符串形式对数字列表的数据框列求和?
【发布时间】:2021-05-07 18:50:42
【问题描述】:

我有一个如下所示的数据框:

| Unit     | Charges                         |
|----------|---------------------------------|
| DW01-100 | trash(15); pest(2)              |
| DW01-101 | trash(15); pest(3)              |
| DW01-102 | garage(150); trash(15); pest(3) |
| DW01-103 | pest(3); trash(15)              |
| DW01-104 | trash(15); pest(3)              |
| DW11-407 | trash(15); pest(3); carport(35) |
| DW11-408 | garage(200); trash(15); pest(3) |
| DW11-409 | trash(15); pest(3)              |
| DW11-410 | carport(35); trash(15); pest(3) |
| DW11-411 | NaN                             |

我想计算所有费用,即括号中的数字,然后将它们相加并将它们存储在一个列中。到目前为止,我正在使用正则表达式 findall

df['Charges'] = df['Charges'].str.findall(r"\((.+?)\)")

提取括号中的所有数字。现在我在每个单元格中都有一个数字列表,以文本形式存储。

我被困在下一步,即将每个数字字符串转换为浮点数并对列中每个单元格的浮点数列表求和。 所需的输出应如下所示:

Unit Charges Summed Charges
DW01-100 trash(15); pest(2) 17
DW01-101 trash(15); pest(3) 18
DW01-102 garage(150); trash(15); pest(3) 168

到目前为止,我已经尝试过这样的apply

def charge_sum(charge_list):
    return sum([float(i) for i in charge_list])

    df['Summed Charges'] = df['Charges'].apply(charge_sum)

这会返回 TypeError: 'float' object is not iterable。

我在这里做错了什么?我认为apply 将单元格作为参数传递给charge_sum 函数,因此输入应该是单个字符串列表,然后列表理解应该将每个str 转换为float 并返回总和。当我把它添加到调试功能中时: print(charge_list) 好像打印了整列

['15', '2']
['15', '3']
['150', '15', '3']
['3', '15']
['15', '3']
['3', '15']
['15']
['15', '3']
['15', '3', '-101.75', '150']
['15', '3', '-88.4']
['15', '3', '-88']
['15', '3', '-89']
['3', '15']
['15', '3', '150']
['15', '2']
['15', '3']
nan

而不仅仅是在出错之前打印第一行 ['15', '2']。为什么将整个列一次传递给 apply 函数,而不是单个单元格?

另外,如果单元格包含nan,如何避免应用该函数?我想我可以fillna(0),但是有更好的方法吗?

【问题讨论】:

    标签: python pandas dataframe data-wrangling


    【解决方案1】:

    试试.str.extractall():

    df["Summed Charges"] = (
        df["Charges"]
        .str.extractall(r"\((\d+)\)")
        .astype(int)
        .groupby(level=0)
        .sum()
    )
    print(df)
    

    打印:

           Unit                          Charges  Summed Charges
    0  DW01-100               trash(15); pest(2)            17.0
    1  DW01-101               trash(15); pest(3)            18.0
    2  DW01-102  garage(150); trash(15); pest(3)           168.0
    3  DW01-103               pest(3); trash(15)            18.0
    4  DW01-104               trash(15); pest(3)            18.0
    5  DW11-407  trash(15); pest(3); carport(35)            53.0
    6  DW11-408  garage(200); trash(15); pest(3)           218.0
    7  DW11-409               trash(15); pest(3)            18.0
    8  DW11-410  carport(35); trash(15); pest(3)            53.0
    9  DW11-411                              NaN             NaN
    

    【讨论】:

    • 谢谢安德烈!这正是我需要的。您对我尝试失败的原因有任何解释吗?
    • @saujosai 在行 9 你有 NaN 值。因此,您尝试遍历此 NaN 值并得到 TypeError。
    【解决方案2】:

    另一种方法:- 将一系列列表转换为数据帧,并使用df.astype 转换为浮点数,然后对axis=1 求和:

    s = df['Charges'].str.findall(r"\((.+?)\)").dropna()
    df['Summed Charges'] = pd.DataFrame(s.tolist(),index=s.index).astype(float).sum(1)
    

    print(df)
    
           Unit                          Charges  Summed Charges
    0  DW01-100               trash(15); pest(2)            17.0
    1  DW01-101               trash(15); pest(3)            18.0
    2  DW01-102  garage(150); trash(15); pest(3)           168.0
    3  DW01-103               pest(3); trash(15)            18.0
    4  DW01-104               trash(15); pest(3)            18.0
    5  DW11-407  trash(15); pest(3); carport(35)            53.0
    6  DW11-408  garage(200); trash(15); pest(3)           218.0
    7  DW11-409               trash(15); pest(3)            18.0
    8  DW11-410  carport(35); trash(15); pest(3)            53.0
    9  DW11-411                              NaN             NaN
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-04
      相关资源
      最近更新 更多