python - 为什么带有两组括号的 .loc 分配会导致 pandas.DataFrame 中的 NaN?
问题描述
我有一个数据框:
姓名 | 年龄 | |
---|---|---|
0 | 保罗 | 25 |
1 | 约翰 | 27 |
2 | 账单 | 23 |
我知道如果我输入:
df[['name']] = df[['age']]
我会得到以下信息:
姓名 | 年龄 | |
---|---|---|
0 | 25 | 25 |
1 | 27 | 27 |
2 | 23 | 23 |
但我希望从命令中得到相同的结果:
df.loc[:, ['name']] = df.loc[:, ['age']]
但相反,我得到了这个:
姓名 | 年龄 | |
---|---|---|
0 | 钠 | 25 |
1 | 钠 | 27 |
2 | 钠 | 23 |
出于某种原因,如果我省略[]
列名周围的方括号,我会得到我所期望的。那是命令:
df.loc[:, 'name'] = df.loc[:, 'age']
给出正确的结果:
姓名 | 年龄 | |
---|---|---|
0 | 25 | 25 |
1 | 27 | 27 |
2 | 23 | 23 |
为什么两对括号的.loc
结果是 NaN?它是某种错误还是预期的行为?我无法弄清楚这种行为的原因。
解决方案
从文档Pandas Data Alignment
(强调我的):
从.loc 和 .iloc设置 Series 和 DataFrame 时,pandas会对齐所有 AXES 。
Basics
您可以在标题下找到标有警告的这段摘录。他们举了一个例子来解释。
In [9]: df[['A', 'B']]
Out[9]:
A B
2000-01-01 -0.282863 0.469112
2000-01-02 -0.173215 1.212112
2000-01-03 -2.104569 -0.861849
2000-01-04 -0.706771 0.721555
2000-01-05 0.567020 -0.424972
2000-01-06 0.113648 -0.673690
2000-01-07 0.577046 0.404705
2000-01-08 -1.157892 -0.370647
In [10]: df.loc[:, ['B', 'A']] = df[['A', 'B']]
In [11]: df[['A', 'B']]
Out[11]:
A B
2000-01-01 -0.282863 0.469112
2000-01-02 -0.173215 1.212112
2000-01-03 -2.104569 -0.861849
2000-01-04 -0.706771 0.721555
2000-01-05 0.567020 -0.424972
2000-01-06 0.113648 -0.673690
2000-01-07 0.577046 0.404705
2000-01-08 -1.157892 -0.370647
来自文档(强调我的):
这不会修改 df 因为列对齐是在赋值之前。
明确避免自动对齐
当您需要在没有索引的情况下执行某些操作(例如,禁用自动对齐)时,访问数组会很有用。
当 LHS 和 RHS 是数据帧时,对齐就会起作用。为避免对齐尝试使用。
df.loc[:, ['B', 'A']] = df[['A', 'B']].to_numpy()
你手头有两个案子,
.loc
与pd.DataFrame
..loc
pd.Series
在编辑中分配。
.loc
分配在pd.DataFrame
Inpd.DataFrame
有 2 个轴index
和columns
. 所以,当你这样做
df.loc[:, ['name']] = df.loc[:, ['age']]
LHS 的列A
与 RHS 列不对齐,B
因此导致NaN
分配后的所有内容。
来自 Docs DataAlignment
(强调我的)
DataFrame 对象之间的数据对齐会自动对齐列和索引(行标签)。同样,生成的对象将具有列和行标签的联合。
如果不是全部,您可以在大多数 pandas 的操作中找到这种行为。例如,加法、减法、乘法等。不匹配的索引和列用 填充NaN
。
数据对齐和算法的示例
df = pd.DataFrame(np.random.randn(10, 4), columns=["A", "B", "C", "D"]) df2 = pd.DataFrame(np.random.randn(7, 3), columns=["A", "B", "C"]) df + df2 A B C D 0 0.045691 -0.014138 1.380871 NaN 1 -0.955398 -1.501007 0.037181 NaN 2 -0.662690 1.534833 -0.859691 NaN 3 -2.452949 1.237274 -0.133712 NaN 4 1.414490 1.951676 -2.320422 NaN 5 -0.494922 -1.649727 -1.084601 NaN 6 -1.047551 -0.748572 -0.805479 NaN 7 NaN NaN NaN NaN 8 NaN NaN NaN NaN 9 NaN NaN NaN NaN
回答您的评论
但是为什么列索引需要匹配呢?我可以看到为什么要匹配行索引,但为什么要匹配列索引?
让我们看一下上面的例子,如果列不对齐,你将如何添加两个 DataFrame?在列和索引上对齐它们是有意义的。
.loc
分配在pd.Series
pd.Series
只有一个轴,即index
。这就是为什么当你这样做时它起作用的原因
df.loc[:, 'name'] = df.loc[:, 'age']
由于pd.Series
只有一个轴,pandas 尝试对齐index
并且成功了。当然,如果index
不对齐,则会产生NaN
值。
来自文档Series Alignment
(强调我的):
未对齐系列之间的操作结果将包含所涉及的索引的并集。如果在一个系列或另一个系列中找不到标签,结果将被标记为缺失
NaN
。
推荐阅读
- kubernetes - 如何在 helm 图表预安装挂钩中关闭 cloud-sql-proxy
- r - R - 使用条件提取部分 xml
- oracle - 如何在 .Net Core 上使用 Oracle DataProvider DB 连接数据库?
- python - 此 Wikipedia Pollard rho 代码示例中是否存在错误?
- linux - 当第一个程序未在 BASH 中退出时使用 2 级管道出现问题
- gcc - 无法从C中的磁盘读取扇区
- c# - 如何在按钮后面传递文本并将其传递给文本框?像“预览”
- c - 为什么我的代码在代码块中不断失败?
- delphi - 执行打开 SQL 数据库的过程时出现 DLL 错误
- python - 虽然我使用 for 循环在 tkinter 的标签上显示所有图像。问题是它只显示一张图片。但我想要所有