我有以下问题:在df中,我想要选择特定的行和特定的列,在这个选择中,获取第一个n
元素,并为它们分配一个新值。我天真地认为以下代码应该可以完成这项工作:
import seaborn as sns
import pandas as pd
df = sns.load_dataset('tips')
df.loc[df.day=="Sun", "smoker"].iloc[:4] = "Yes"
loc
和iloc
都应将视图返回到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]
之间的差异。
在您的情况下,可以定义要插补的列
假设下面的数据集
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
我相信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代码中是如何定义的)。 本例中的括号是否只是函数调用的语法糖?如果是这样,那么如何让任意函数使用括号而不是括号呢?否则,它们的使用/定义有什么特殊之处?