我正在编写一些代码,在pandas DataFrame中使用.loc时遇到了一些意外行为,具体取决于数据帧本身的长度。希望就正在发生的事情以及如何避免产生不一致的产出提供一些指导。
首先,我正在使用Python 3.11和pandas 2.2.2版本。问题是,根据数据帧长度,.loc将返回一个单项序列或float64对象。下面是我制作的一些虚拟示例的复制品。
首先,当考虑具有多索引的较长数据帧时,返回具有.loc的Series
df = pd.DataFrame.from_dict(
{'ix1': ['asd', 'asd', 'asd', 'qwe', 'qwe', 'qwe', 'qwe', 'asd', 'qwe', 'asd', 'asd', 'qwe', 'asd', 'asd', 'asd', 'asd', 'qwe', 'qwe', 'qwe', 'qwe', 'asd', 'qwe', 'qwe', 'asd', 'qwe', 'qwe', 'qwe', 'asd', 'asd', 'asd', 'bar', 'qwe', 'qwe', 'asd', 'qwe', 'asd'],
'ix2': ['sdf', 'bar', 'rty', 'fgh', 'cvb', 'cvb', 'vbn', 'bnm', 'jkl', 'ewq', 'uio', 'uio', 'wer', 'dsa', 'vbn', 'cxz', 'sdf', 'iuo', 'bar', 'bvc', 'fgh', 'rty', 'gfd', 'cvb', 'wer', 'bnm', 'ewq', 'tre', 'uyt', 'jhg', 'foo', 'dsa', 'mnb', 'jkl', 'iuy', 'lkj'],
'value': [float(i) for i in range(1, 37)]})
>>> df[['ix1', 'ix2', 'value']].set_index(['ix1', 'ix2']).loc[('bar', 'foo'), 'value']
# <input>:1: PerformanceWarning: indexing past lexsort depth may impact performance.
# ix1 ix2
# bar foo 31.00
# Name: value, dtype: float64
返回PerformanceWarning,因为索引未排序,且序列值为float64(不需要)
更短的数据帧,相同的结构,相同的索引,执行的代码行相同,返回float64代替
df = pd.DataFrame.from_dict(
{'ix1': ['foo', 'foo', 'foo', 'foo', 'foo', 'foo', 'foo', 'bar'],
'ix2': ['tyu', 'fgh', 'vbn', 'jkl', 'foo', 'asd', 'qwe', 'foo'],
'value': [float(i) for i in range(1, 9)]})
>>> df[['ix1', 'ix2', 'value']].set_index(['ix1', 'ix2']).loc[('bar', 'foo'), 'value']
# np.float64(8.0)
只需返回一个float64(根据需要)
这在后面的代码中造成了麻烦,因为我需要浮点数来执行一些计算,而且我似乎不知道该怎么做才能生成一致的输出。