Pandas for 循环没有用 iloc 正确更新行?

Posted

技术标签:

【中文标题】Pandas for 循环没有用 iloc 正确更新行?【英文标题】:Pandas for loop not updating rows correctly with iloc? 【发布时间】:2020-02-24 22:11:33 【问题描述】:

我正在尝试编写一个脚本,该脚本将根据列重复项(“电子邮件”)遍历 df,并将信息从旧行更新到最新行(列 =“创建于”)。最近一行中的一些数据是 NaN,因此当该行不是 NaN 时,需要由旧行更新此数据。我的数据集非常大,有很多列。我已经按照正确的顺序对列表进行了排序:

crm_dupes_s = dupes_df.sort_values(["Email", "Created On"], ascending=False)
crm_dupes_s.head(25)

然后确保正确读取 NaN 值:

crm_dupes_nan = crm_dupes_s.replace('nan', np.NaN)
crm_dupes_nan.isna()

  Full Name First Name  Middle Name Last Name   Status   Email   Created On 
0 False     False       True        True        False    False   False
1 False     False       True        False       False    False   False

为以后的循环迭代列出了列,但由于这些值没有被更新而取出了电子邮件:

cols_to_change = list(crm_dupes_nan.columns)
cols_to_change.remove('Email')
cols_to_change

[' Full Name',
 'First Name',
 'Middle Name',
 'Last Name',
 'Status',
 'Created On']

最后是我的 for 循环:

#Iterates through all rows

for i in range(0, crm_dupes_nan.shape[0]):

#If there is a value for Email

    if not pd.isna(crm_dupes_nan.iloc[i-1, :]['Email']): 

#If the row Email values are the same "duplicates" then execute cell value change

        if crm_dupes_nan.iloc[i-1, :]['Email'] == crm_dupes_nan.iloc[i, :]['Email']:  
            for col in cols_to_change:
                if not pd.isna(crm_dupes_nan.iloc[i-1, :][col]):
                    crm_dupes_nan.iloc[i-1, :][col] = crm_dupes_nan.iloc[i, :][col]

我知道前 3 行正确识别重复,但“iloc”函数没有改变 NaN 值??我尝试过“iat”、“set_value”、“replace”和“where”,但都遇到了各种问题。我的印象是“iloc”是任务和性能的首选方法。任何帮助将不胜感激!!!

Full Name   First Name  Middle Name Last Name   Status  Email   Account Numbers Primary Account Number  Business Phone  Home Phone
0   Zac Daniels  Zac    NaN   Hopkins  Active   zdaniels@gmail.com   NaN            3452432.0    NaN    NaN
1   Zac Daniels  Zac    NaN   Hopkins  Active   zdaniels@gmail.com 13254512.0   4564534.0    (949) 803-8033   (817) 817-9177    
2   Zach Fred    Zach   NaN   Wilbern  Active   zFredericks@miami.com 45632532.0    12342313.0   (313) 313-3133   (313) 313-3133

【问题讨论】:

这个crm_dupes_nan.iloc[i-1, :][col] 有链式索引的问题。阅读此处了解更多信息:pandas.pydata.org/pandas-docs/stable/user_guide/… 考虑重写crm_dupes_nan.iloc[i-1, crm_dupes_nan.columns.get_indexer(col)] 罗杰检查... 与电子邮件类似...crm_dupes_nan.iloc[i, crm_dupes_nan.columns.get_indexer(['email'])]。一般来说,如果你在 pandas 中看到 ][,那就不好了。 我觉得您的问题可以在不循环抛出行并手动更新的情况下解决。你能分享你的dupes_df吗? 【参考方案1】:

很难更改 pandas 数据帧的单个值,我怀疑这是开发人员故意的。 pandas 的重点是高效地处理表格数据,而无需遍历行和列。当您使用 crm_dupes_nan.iloc[i-1, :][col] 进行子集化时,您会得到不再与数据框绑定的变量,因此无法为其分配值。

我认为您可能需要查看 pd.groupby 来收集您的电子邮件组,使用您要填写的数据形成一个更新程序数据框,然后使用 pd.merge 或 pd.update 替换 nan 值在带有更新程序值的 crm_dupes 中。留给读者练习的细节。 :-)

【讨论】:

我明白了....谢谢!我曾尝试对数据进行分组,但在分离电子邮件重复项和合并值以摆脱 NaN 时遇到了麻烦,但我想一遍又一遍地尝试是该过程的一部分,哈哈

以上是关于Pandas for 循环没有用 iloc 正确更新行?的主要内容,如果未能解决你的问题,请参考以下文章

基于条件更改行值的 Python for 循环可以正常工作,但不会更改 pandas 数据帧上的值?

Pandas for 在组上循环

如何从 for 循环返回多个具有唯一名称的 pandas 数据帧?

iloc[ ]函数(Pandas库)

Pandas:使用 .iloc 对多列求和,但也包括绝对值

Python Pandas 遍历DataFrame的正确姿势 速度提升一万倍