我有一个名为input.csv
的简单CSV文件,如下所示:
name,money
Dan,200
Jimmy,xd
Alice,15
Deborah,30
我想写一个python脚本来消毒money
列中的数据:每个包含非数字字符的值都需要替换为0
这是我到目前为止的尝试:
import pandas as pd
df = pd.read_csv(
"./input.csv",
sep = ","
)
# this line is the problem: it doesn't update on a row by row basis, it updates all rows
df['money'] = df['money'].replace(to_replace=r'[^0‐9]', value=0, regex=True)
df.to_csv("./output.csv", index = False)
问题是,当脚本运行时,因为其中一行存在invalud money valuexd
,它将更改所有行的所有money value为0。
我希望它只改变第二个数据行(Jimmy)的货币值,该数据行具有无效值。
这是它在结尾给出的内容:
name,money
Dan,0
Jimmy,0
Alice,0
Deborah,0
但我需要它给的是:
name,money
Dan,200
Jimmy,0
Alice,15
Deborah,30
有什么问题吗?
您可以使用:
df['money'] = pd.to_numeric(df['money'], errors='coerce').fillna(0).astype(int)
以上假设所有有效值都是整数。如果您想要浮点值,可以不使用.astype(int)
。
另一种选择是在read_csv
方法中使用转换函数。同样,这里假设的是整数。如果您期望浮动货币值,则可以使用float(x)
代替int(x)
:
def convert_to_int(x):
try:
return int(x)
except ValueError:
return 0
df = pd.read_csv(
'input.csv',
converters={'money': convert_to_int}
)
一些列表理解可以解决这个问题(考虑到"money"列中没有小数):
df.money = [x if type(x) == int else 0 for x in df.money]
如果你处理的是小数,那么像这样:
df.money = [x if (type(x) == int) or (type(x) == float) else 0 for x in df.money]
…将工作。只要知道熊猫会把所有的"钱"都换成熊猫就行了。