python - 将列表插入单元格 - 为什么 loc 实际上在这里工作?

标签 python pandas list indexing

我们知道设置单个单元格的标准方法是使用atiat。但是,我注意到一些有趣的行为,我想知道是否有人可以合理化。

在解决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 这样做?这是记录在案的行为,还是错误?

最佳答案

这是因为 loc 做了一个 bunch检查它支持的所有许多用例。 (注意:历史是 lociloc 是为了消除 ix 的歧义而创建的,早在 2013 年 v0.11,但即使在今天loc 中仍然有很多歧义。)

在这种情况下,df.loc[1, 'B'] 可以返回:

  • 单个元素(在本例中,当 1/'B' 有一个唯一的索引/列时)。
  • 一个系列(如果 1/'B' 之一多次出现在索引/列中)。
  • 一个 DataFrame(如果 BOTH 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]

它仍然不理想,但重申在 lociloc 中有太多边缘情况,解决方案是尽可能明确地避免它们(在此处使用 at)。更一般地说,如您所知,避免在 DataFrame 中使用列表!

关于python - 将列表插入单元格 - 为什么 loc 实际上在这里工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54400137/

相关文章:

python - numpy 数组中的索引

python - 加载序列化 json 对象时出现问题

python:Pandas groupby 和应用优化

c# - 有条件地从列表中获取总和

python - 在装饰器中使用 Wraps 时会出现 TypeError

Python:如果不是字符串,请使用重新输入输入并将用户输入转换为小写

python - 删除反向重复项

c++ - 让类存储未知数据

css - 多级 ul 列表定位

Python 参数计数