当前位置: 首页 > 知识库问答 >
问题:

在链接loc和iloc后更改熊猫中的值

赫连冠玉
2023-03-14

我有以下问题:在df中,我想要选择特定的行和特定的列,在这个选择中,获取第一个n元素,并为它们分配一个新值。我天真地认为以下代码应该可以完成这项工作:

import seaborn as sns
import pandas as pd

df = sns.load_dataset('tips')
df.loc[df.day=="Sun", "smoker"].iloc[:4] = "Yes"

lociloc都应将视图返回到df中,并且应覆盖该值。但是,数据帧不会改变。为什么?

我知道如何绕过它--首先使用loc创建一个新的df,然后使用iloc更改值并更新原始df(如下所示)。

但是a)我不认为这是最佳的,b)我想知道为什么顶级解决方案不起作用。为什么它返回一个副本而不是视图的视图?

替代解决方案:

df = sns.load_dataset('tips')
tmp = df.loc[df.day=="Sun", "smoker"]
tmp.iloc[:4] = "Yes"
df.loc[df.day=="Sun", "smoker"] = tmp

注意:我已经阅读了文档,这篇非常棒的帖子和这个问题,但是他们没有解释这一点。他们关心的是df.loc[mask,“z]和链接的df[“z”][mask]之间的差异。

共有2个答案

狄安歌
2023-03-14

在您的情况下,可以定义要插补的列

假设下面的数据集

df = pd.DataFrame(data={'State':[1,2,3,4,5,6, 7, 8, 9, 10], 
                         'Sno Center': ["Guntur", "Nellore", "Visakhapatnam", "Biswanath", "Nellore", "Guwahati", "Nellore", "Numaligarh", "Sibsagar", "Munger-Jamalpu"], 
                         'Mar-21': [121, 118.8, 131.6, 123.7, 127.8, 125.9, 114.2, 114.2, 117.7, 117.7],
                         'Apr-21': [121.1, 118.3, 131.5, 124.5, 128.2, 128.2, 115.4, 115.1, 117.3, 118.3]})
df
    State   Sno Center      Mar-21  Apr-21
0   1       Guntur          121.0   121.1
1   2       Nellore         118.8   118.3
2   3       Visakhapatnam   131.6   131.5
3   4       Biswanath       123.7   124.5
4   5       Nellore         127.8   128.2
5   6       Guwahati        125.9   128.2
6   7       Nellore         114.2   115.4
7   8       Numaligarh      114.2   115.1
8   9       Sibsagar        117.7   117.3
9   10      Munger-Jamalpu  117.7   118.3

因此,我想将Sno Center等于Nellore

mask = df["Sno Center"] == "Nellore"
df.loc[mask, ["Mar-21", "Apr-21"]] = 0

结果

df
State   Sno Center      Mar-21  Apr-21
0   1   Guntur          121.0   121.1
1   2   Nellore         0.0     0.0
2   3   Visakhapatnam   131.6   131.5
3   4   Biswanath       123.7   124.5
4   5   Nellore         0.0     0.0
5   6   Guwahati        125.9   128.2
6   7   Nellore         0.0     0.0
7   8   Numaligarh      114.2   115.1
8   9   Sibsagar        117.7   117.3
9   10  Munger-Jamalpu  117.7   118.3

另一个选项是将列定义为列表

COLS = ["Mar-21", "Apr-21"]
df.loc[mask, COLS] = 0

使用iloc的其他选项

COLS = df.iloc[:, 2:4].columns.tolist()
df.loc[mask, COLS] = 0

df.loc[mask, df.iloc[:, 2:4].columns.tolist()] = 0
暴绪
2023-03-14

我相信df.loc[].iloc[]是一个链式分配案例,pandas不能保证您在最后会看到一个视图。从文档中:

是否为设置操作返回副本或引用,可能取决于上下文。这有时被称为链式赋值,应该避免。

由于您在loc中有一个过滤条件,熊猫将创建一个新的pd。Series和than将对其应用赋值。例如,以下方法将起作用,因为您将获得与df["吸烟者"]相同的系列:

df.loc[:, "smoker"].iloc[:4] = 'Yes'

但您将得到“设置为CopyWarning”警告。

您需要重写代码,以便pandas将其作为单个loc实体处理。

另一种可能的解决方法

df.loc[df[df.day=="Sun"].index[:4], "smoker"] = 'Yes'
 类似资料:
  • 假设我有下面的数据框,我想将

  • 参考这个答案,Lev说包括开始和停止索引,所以我尝试了这个: 但它们也不同。为什么啊? 有人能帮我吗?

  • 我对pandas的iloc函数有点困惑,因为我想选择一系列列,并且输出与预期不同。行选择也会发生同样的情况,因此我编写了一个小示例: 我想选择第1行到第2行结果是我所期望的: 如果我这样做我会认为我得到了相同的结果,但是没有: 我有点困惑,因为我希望这两个函数的行为相同,但如果我选择一个范围(从:到),这两个函数的输出都会不同。 似乎使用iloc需要将TO值设为1,才能获得与loc: 有人能给它点

  • 所以我运行了一些示例: 类似于: 让我们使用和并确保得到相同的内容 这就是说,谁能提供关于方法可以做什么和不能做什么的指导呢?

  • 最近开始从我的安全地带(R)扩展到Python,我对中的单元格定位/选择感到有点困惑。我已经阅读了文档,但我很难理解各种本地化/选择选项的实际含义。 我是否有理由使用或而不是,以及,反之亦然?在什么情况下我应该使用哪种方法? 注意:以后的读者要知道,这个问题已经过时了,是在熊猫v0.20之前写的,当时有一个函数叫做。这个方法后来被分成两个-和-以明确区分位置索引和基于标签的索引。请注意,由于不一致

  • 因此.loc和.iloc不是典型的函数。它们以某种方式使用[和]来包围参数,使其与普通数组索引相当。然而,我从未在另一个库中看到过这种情况(我可以想到,可能numpy就是这样的东西,我不知道它在技术上是如何工作的/在python代码中是如何定义的)。 本例中的括号是否只是函数调用的语法糖?如果是这样,那么如何让任意函数使用括号而不是括号呢?否则,它们的使用/定义有什么特殊之处?