如何以字符串形式对数字列表的数据框列求和?
How to sum a dataframe column of lists of numbers in string form?
我有一个如下所示的数据框:
| 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)
这个 returns 类型错误:'float' 对象不可迭代。
我在这里做错了什么?我认为 apply
将单元格作为参数传递给 charge_sum
函数,因此输入应该是一个字符串列表,然后列表理解应该将每个 str
转换为 float
和 return 的总和。当我把这个添加到函数中进行调试时:
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']。为什么一次将整列而不是单个单元格传递给应用函数?
此外,如果单元格包含 nan
,如何避免应用该函数?我想我可以 fillna(0)
,但有更好的方法吗?
尝试 .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
另一种方法:- 将一系列列表转换为数据帧,并使用 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
我有一个如下所示的数据框:
| 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)
这个 returns 类型错误:'float' 对象不可迭代。
我在这里做错了什么?我认为 apply
将单元格作为参数传递给 charge_sum
函数,因此输入应该是一个字符串列表,然后列表理解应该将每个 str
转换为 float
和 return 的总和。当我把这个添加到函数中进行调试时:
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']。为什么一次将整列而不是单个单元格传递给应用函数?
此外,如果单元格包含 nan
,如何避免应用该函数?我想我可以 fillna(0)
,但有更好的方法吗?
尝试 .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
另一种方法:- 将一系列列表转换为数据帧,并使用 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