首页 > 解决方案 > 通过 .at 和 MultiIndex 从 pd.DataFrame 中选择显式单元格

问题描述

我有一个基于 MultiIndex 的 pd.DataFrame:

import pandas as pd
data = pd.DataFrame([[2, 3], [4, 5], [6, 7], [8, 9], [10, 11], [12, 13]], index=pd.MultiIndex.from_tuples([
            (pd.Timestamp('2019-07-01 23:00:00'), pd.Timestamp('2019-07-01 23:00:00'), 0),
            (pd.Timestamp('2019-07-02 00:00:00'), pd.Timestamp('2019-07-02 00:00:00'), 0),
            (pd.Timestamp('2019-07-02 00:00:00'), pd.Timestamp('2019-07-02 00:00:00'), 0),
            (pd.Timestamp('2019-07-02 01:00:00'), pd.Timestamp('2019-07-02 01:00:00'), 0),
            (pd.Timestamp('2019-07-02 02:00:00'), pd.Timestamp('2019-07-02 02:00:00'), 0),
            (pd.Timestamp('2019-07-02 03:00:00'), pd.Timestamp('2019-07-02 03:00:00'), 0)],
           names=['dt_calc', 'dt_fore', 'positional_index']), columns=['temp', 'temp_2'])

现在我想用列表对象替换单元格(之前将 DataFrame 类型转换为对象):

idx = data.index[0]
data.at[idx, 'temp'] = [1,2,3]

这将产生:

ValueError                                Traceback (most recent call last)
/app/generic_model/modules/feature_engineering/lstm_pre_processing.py in <module>
----> 1 data.at[idx, 'temp']

/usr/local/lib/python3.8/dist-packages/pandas/core/indexing.py in __getitem__(self, key)
   2151             # GH#33041 fall back to .loc
   2152             if not isinstance(key, tuple) or not all(is_scalar(x) for x in key):
-> 2153                 raise ValueError("Invalid call for scalar access (getting)!")
   2154             return self.obj.loc[key]
   2155 

ValueError: Invalid call for scalar access (getting)!

我不知道问题是什么,因为使用.loc效果很好。但是.loc我无法替换单元格值。在这种情况下,错误消息并没有真正的帮助。

pd.__version__: 1.2.2在 python 3.8 上运行。

标签: pythonpandasdataframemulti-index

解决方案


我们仍然可以loc通过创建具有与需要更新的单元格对应的相同索引的中间系列来分配单个单元格的值。附带说明一下,将复杂对象存储在 pandas 列中通常不是一个好习惯,因为您将失去矢量化的好处。

data.loc[idx, 'temp'] = pd.Series([[1, 2, 3]], index=[idx])

                                                               temp  temp_2
dt_calc             dt_fore             positional_index                   
2019-07-01 23:00:00 2019-07-01 23:00:00 0                 [1, 2, 3]       3
2019-07-02 00:00:00 2019-07-02 00:00:00 0                         4       5
                                        0                         6       7
2019-07-02 01:00:00 2019-07-02 01:00:00 0                         8       9
2019-07-02 02:00:00 2019-07-02 02:00:00 0                        10      11
2019-07-02 03:00:00 2019-07-02 03:00:00 0                        12      13

推荐阅读