将列表插入单元格 - 为啥 loc 实际上在这里工作?
Posted
技术标签:
【中文标题】将列表插入单元格 - 为啥 loc 实际上在这里工作?【英文标题】:Inserting list into a cell - why does loc ACTUALLY work here?将列表插入单元格 - 为什么 loc 实际上在这里工作? 【发布时间】:2019-06-21 08:18:27 【问题描述】:我们知道设置单个单元格的标准方法是使用at
或iat
。但是,我注意到一些有趣的行为,我想知道是否有人可以合理化。
在解决this question 时,我遇到了loc
的一些奇怪行为。
# Setup.
pd.__version__
# '0.24.0rc1'
df = pd.DataFrame('A': [12, 23], 'B': [['a', 'b'], ['c', 'd']])
df
A B
0 12 [a, b]
1 23 [c, d]
要设置单元格 (1, 'B'),使用 at 就足够了,例如 df.at[1, 'B'] = ...
。但是对于 loc,我最初尝试过这个,但没有奏效:
df.loc[1, 'B'] = ['m', 'n', 'o', 'p']
# ValueError: Must have equal len keys and value when setting with an iterable
所以,我尝试了(也失败了)
df.loc[1, 'B'] = [['m', 'n', 'o', 'p']]
# ValueError: Must have equal len keys and value when setting with an ndarray
我认为loc
也可以在这里获取嵌套列表。在一个奇怪的事件中,这个代码起作用了:
df.loc[1, 'B'] = [['m'], ['n'], ['o'], ['p']]
df
A B
0 12 [a, b]
1 23 [m, n, o, p]
为什么loc
会这样工作?此外,如果您将另一个元素添加到任何列表中,它会失败:
df.loc[1, 'B'] = [['m'], ['n'], ['o'], ['p', 'q']]
# ValueError: Must have equal len keys and value when setting with an iterable
空列表也不起作用。必须将每个元素嵌套在自己的列表中似乎毫无意义。
loc
为什么要这样做?这是记录在案的行为,还是错误?
【问题讨论】:
这在我看来像是一个不受支持的功能,你可以称之为错误或不一致,当然存储非标量类型是不明智的。有趣的是,.at
的使用限制较少
【参考方案1】:
这是因为loc
执行bunch 检查它支持的所有许多用例。 (注意:历史是 loc
和 iloc
是为了消除 ix
的歧义而创建的,早在 2013 年 v0.11 中,但即使在今天,loc
仍然存在很多歧义。)
在这种情况下,df.loc[1, 'B']
可以返回:
除此之外:iloc
在这种情况下会遇到同样的问题,尽管它总是第一种情况,但这可能是因为 loc 和 iloc 共享此分配代码。
因此,pandas 需要支持所有这些情况进行分配!
分配逻辑的早期部分将列表(列表)转换为 numpy 数组:
In [11]: np.array(['m', 'n', 'o', 'p']).shape
Out[11]: (4,)
In [12]: np.array([['m', 'n', 'o', 'p']]).shape
Out[12]: (1, 4)
因此,您不能只传递列表列表并期望获得正确的数组。相反,您可以明确设置为对象数组:
In [13]: a = np.empty(1, dtype=object)
In [14]: a[0] = ['m', 'n', 'o', 'p']
In [15]: a
Out[15]: array([list(['m', 'n', 'o', 'p'])], dtype=object)
现在你可以在作业中使用它了:
In [16]: df.loc[0, 'B'] = a
In [17]: df
Out[17]:
A B
0 12 [m, n, o, p]
1 23 [c, d]
这仍然不理想,但重申loc
和iloc
中有太多边缘情况,解决方案应尽可能明确以避免它们(在此处使用at
)。如您所知,更一般地,避免在 DataFrame 中使用列表!
【讨论】:
哦,我想我还没回答第二部分。 答案是“它偷偷溜走”(我链接到的一堆支票)。稍后我会尝试用更具体的内容对其进行修改。 所以“状态设计”? :D @coldspeed status-by-duct-taped-together-working-well-enough :)以上是关于将列表插入单元格 - 为啥 loc 实际上在这里工作?的主要内容,如果未能解决你的问题,请参考以下文章