Pandas: .ix的替代方法

21

由于pandas 0.20.0的更新以及.ix被弃用 (详情请见),我想知道使用剩余的.loc.iloc获取相同结果的最有效方法。我刚刚回答了这个问题,但第二种选项(不使用.ix)似乎效率较低且过于冗长。

片段:

print df.iloc[df.loc[df['cap'].astype(float) > 35].index, :-1]

当同时使用条件和索引位置过滤时,这是否是正确的方法?

4个回答

14

通过使用位置对特定的索引进行切片,您可以留在单个loc世界中并获得所需的索引值。

df.loc[
    df['cap'].astype(float) > 35,
    df.columns[:-1]
]

10

通常情况下,在pandas中,您会尽量避免使用链式索引(尽管严格来说,您实际上正在使用两种不同的索引方法)。这种方式不能修改您的数据框架(详情请参见文档),并且文档中还提到性能是另一个原因(与仅进行一次索引相比进行两次索引)。

对于性能问题,通常它是微不足道的(或者说不太可能成为代码瓶颈),而实际上似乎并非如此(至少在以下示例中不是):

df = pd.DataFrame(np.random.uniform(size=(100000,10)),columns = list('abcdefghij'))
# Get columns number 2:5 where value in 'a' is greater than 0.5 
# (i.e. Boolean mask along axis 0, position slice of axis 1)

# Deprecated .ix method
%timeit df.ix[df['a'] > 0.5,2:5]
100 loops, best of 3: 2.14 ms per loop

# Boolean, then position
%timeit df.loc[df['a'] > 0.5,].iloc[:,2:5]
100 loops, best of 3: 2.14 ms per loop

# Position, then Boolean
%timeit df.iloc[:,2:5].loc[df['a'] > 0.5,]
1000 loops, best of 3: 1.75 ms per loop

# .loc
%timeit df.loc[df['a'] > 0.5, df.columns[2:5]]
100 loops, best of 3: 2.64 ms per loop

# .iloc
%timeit df.iloc[np.where(df['a'] > 0.5)[0],2:5]
100 loops, best of 3: 9.91 ms per loop

底线:如果你真的想避免使用.ix,并且不打算修改数据帧中的值,那么就使用链式索引。另一方面(“正确”的但可能更混乱的方式),如果你确实需要修改值,则可以使用.iloc配合np.where()或者使用df.indexdf.columns的整数切片来使用.loc


3

将这个过程分为两步索引怎么样:

df[df['cap'].astype(float) > 35].iloc[:,:-1]

甚至可以:
df[df['cap'].astype(float) > 35].drop('cap',1)

好的,显然我一开始在那里不需要.loc,所以谢谢您。这肯定有效 - 那么总的来说,.ix被弃用是否迫使需要进行这些类型查询的两步索引? - elPastor
不一定,例如使用 loc,您可以执行 df.loc[df['cap'].astype(float) > 35, :"Marketcap"],尽管仍无法使用基于位置的索引。 - Psidom
Psidom,我选择接受@piRSquared,因为对我来说这是最直观的过渡。但是你的方法让我开始思考新的方向,再次感谢。 - elPastor

0

Pandas已经移除了.ix,鼓励您使用.iloc和.loc。

为此,您可以参考iloc、loc的定义以及它们与ix的区别,这可能会对您有所帮助。

iloc、ix和loc有什么不同?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接