python - “你永远不应该修改你正在迭代的东西”。那我该如何修改呢?
问题描述
我在这里阅读了Pandas 文档和许多评论,你不应该修改你正在迭代的东西。
假设我有这个dataframe
:
mydf = pd.DataFrame({'name':['jim','john','mary','michael'],
'age':[12,46,44,32]})
name age
0 jim 12
1 john 46
2 mary 44
3 michael 32
我想做以下事情:
1.如果名称以 开头j
,则添加'smith'
到名称中。
2.如果年龄大于 40,则乘以 2。
所以我创建了一个函数来做到这一点:
def modify(df):
for i in range(len(df)):
# if age is >40
if df.loc[i,'age'] > 40:
# multiply it by 2
df.loc[i,'age'] = df.loc[i,'age']*2
# get the name
name = df.loc[i,'name']
# if it starts with 'j'
if name[0]=='j':
# add 'smith' to the name
name = name+' '+'smith'
# insert into cell
df.loc[i,'name'] = name
应用功能:
modify(mydf)
结果:
print(mydf)
name age
0 jim smith 12
1 john smith 92
2 mary 88
3 michael 32
这工作得很好。所以有什么问题?
我应该复制数据框并在最后返回吗?如下所示:
def modify(df):
df = df.copy()
for i in range(len(df)):
if df.loc[i,'age'] > 40:
df.loc[i,'age'] = df.loc[i,'age']*2
name = df.loc[i,'name']
if name[0]=='j':
name = name+' '+'smith'
df.loc[i,'name'] = name
return df
但是,我仍在编辑我正在迭代的内容。所以我想这仍然很糟糕?
注意:我正在开发一个比这更大、更复杂的函数,它有更多的条件和 api 调用等,它会遍历 100,000 行客户数据。例如,如果客户来自 X 市do this
,如果客户来自 Y 市,do that
等等。所以我不是在寻找这个确切数据框的解决方案。
我只想知道如果您必须在完全不推荐的情况下迭代和编辑行时该怎么办。
解决方案
在for
使用pandas
. pandas
代表优化这些循环。
这是解决您的问题的代码:
idx_smith = mydf[mydf["name"].str.startswith("j")].index
idx_age = mydf[mydf["age"] > 40].index
mydf.loc[idx_smith, "name"] = mydf.loc[idx_smith].name + " smith"
mydf.loc[idx_age, "age"] = mydf.loc[idx_age].age*2
mydf
name age
0 jim smith 12
1 john smith 92
2 mary 88
3 michael 32
对您的问题的回答:您应该使用迭代来进行行操作pandas 适用于 lambda以提高内存/cpu 使用率。
推荐阅读
- machine-learning - 用于训练对象检测模型的训练集中的重复对象
- powershell - Windows Powershell 'if' 总是返回 $true - 我做错了什么?
- javascript - 如何优化下面的过滤器逻辑以仅使用 1 个循环而不是 2 个?
- sqlite - SQLite 中的 TEXT NOT NULL UNIQUE 列是否有字符长度限制?
- webserver - 无法将 Caddy 服务器配置为将 TLS 与我的域名一起使用
- java - Tomcat 9 错误 - mysql-cj-abandoned-connection-cleanup
- python - 使用warnings.simplefilter('error')时jupyter笔记本可能存在错误?
- python - 如何在python中获取组合框选定项的值
- swift - 属性包装初始化程序中缺少参数“initialValue”的参数;添加 'wrappedValue' 和 'initialValue' 参数
- spring - @Valid 在@RestController 上没有@Validated 是否可以工作?