我正在编写一些代码,并且在 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,因为索引未排序且 Series 具有 float64 值(不需要)
更短的数据帧,相同的结构,相同的索引,执行相同的代码行,返回 float64 insted
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(根据需要)
这会在代码中造成麻烦,因为我需要浮点数来执行一些计算,而且我似乎没有找到应该做什么来生成一致的输出。
您的第二个示例没有重复的
ix1
/ix2
组合,这可以防止出现此问题。
如果你总是想要一个浮动我会使用:
cols = ['ix1', 'ix2']
df.drop_duplicates(cols).set_index(cols)['value'].loc[('bar', 'foo')]
输出:
31.0