在iterrows循环中修改pandas数据框

4

我是一名Python新手。

我正在尝试使用for循环向数据框中的元素添加前缀(序列号),以便在分析之前进行数据清理/准备。

代码如下:

a=pd.read_excel('C:/Users/HP/Desktop/WFH/PowerBI/CMM data.xlsx','CMM_unclean')
a['Serial Number'] = a['Serial Number'].apply(str)
print(a.iloc[72,1])

for index,row in a.iterrows():
    if len(row['Serial Number']) == 6:
        row['Serial Number'] = 'SR0' + row['Serial Number']
        print(row['Serial Number'])

print(a.iloc[72,1])

输出结果为:
C:\Users\HP\anaconda3\envs\test\python.exe C:/Users/HP/PycharmProjects/test/first.py
101306
SR0101306
101306

我不明白为什么在for循环内部这个值正在改变,但是在外部它却保持不变。
3个回答

3

这不会改变名为a的实际数据帧。

简而言之:从iterrows返回的行是副本,不再与原始数据帧连接,因此编辑不会更改您的数据帧。但是,您可以使用索引访问和编辑数据帧的相关行。


解释

为什么?

iterrows返回的行是副本,已经不再连接到原始数据帧,因此编辑不会更改您的数据帧。但是,您可以使用index访问和编辑数据帧的相关行。


解决方法如下:

import pandas as pd

a = pd.read_excel("Book1.xlsx")
a['Serial Number'] = a['Serial Number'].apply(str)

a.head()
#    ID    Serial Number
# 0   1     SR0101306
# 1   2       1101306

print(a.iloc[0,1])
#101306

for index,row in a.iterrows():
    row = row.copy()
    if len(row['Serial Number']) == 6:
        # use the index and .loc method to alter the dataframe
        a.loc[index, 'Serial Number'] = 'SR0' + row['Serial Number']

print(a.iloc[0,1])
#SR0101306

非常感谢。这是很好的解释。 - Saurabh Arya
很高兴我能帮忙。如果有帮助,请考虑给我的回答点个赞。 - seralouk

1

在文档中, 我读到了以下内容(强调来自原文)

绝不能修改正在迭代的内容。这并不保证在所有情况下都能正常工作。根据数据类型,迭代器返回一个副本而不是视图,对其进行写入将没有任何效果。

也许这意味着在您的情况下会创建一个副本而不是使用引用。因此更改仅暂时应用于副本,而不是数据帧中的数据。


谢谢Wolf先生,这非常有用。 - Saurabh Arya

0

既然您已经在使用apply,那么您可以在调用apply的函数内直接完成此操作:

def fix_serial(n):
    n_s = str(n)

    if len(n_s) == 6:
        n_s = 'SR' + n_s

    return n_s

a['Serial Number'] = a['Serial Number'].apply(fix_serial)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接