为什么loc和iloc在对Pandas DataFrame的行进行切片时会有所不同?

时间:2018-07-08 05:50:25

标签: python pandas

我想要一个DataFrame,其中一列的顶部行(称为“ cat”)的值为“ LOW”,框架的中部和底部的值为“ MID”和“ HI”。因此,对于包含1,200行的帧,cat列的值计数应得出:

LOW    400
MID    400
HI     400

这应该很容易。但是,显然并非如此。无济于事,我尝试使用df.loc[-400:,["cat"]] = "HI"

选择和更改底部的行

但是,这种方法确实适用于前几行:df.loc[:399,["cat"]] = "LOW"

下面的示例显示了一个有效的示例,请注意,它同时需要lociloc。这是大熊猫可以改善的地方吗?

import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.random([1200, 4]), columns=['A', 'B', 'C', 'D'])
df["cat"] = "MID"
df.loc[:399,["cat"]] = "LOW"
df.iloc[-400:,-1] = "HI"  # The -1 selects the last column ('cat') - not ideal.
df.cat.value_counts()

2 个答案:

答案 0 :(得分:2)

如果要按cat按位置进行选择,请使用get_loc作为列iloc的位置-需要索引和列的位置:

df = pd.DataFrame(np.random.random([1200, 4]), columns=['A', 'B', 'C', 'D'])
df["cat"] = "MID"

df.iloc[:400,df.columns.get_loc('cat')] = "LOW"
df.iloc[-400:,df.columns.get_loc('cat')] = "HI"

详细信息

print (df.columns.get_loc('cat'))
4

替代方法是使用loc用于按标签选择-然后需要通过索引选择400的索引值:

df.loc[df.index[:400],"cat"] = "LOW"
df.loc[df.index[-400:],"cat"] = "HI"

a = df.cat.value_counts()
print (a)
MID    400
HI     400
LOW    400
Name: cat, dtype: int64

设置400个值的另一种方法是使用numpy.repeat或通过重复列表设置值:

df["cat"] =  np.array(["LOW", "MID", "HI"]).repeat(400)

df["cat"] =  ["LOW"] * 400 + ["MID"] * 400 +  ["HI"] * 400
#thanks  @Quickbeam2k1
df = df.assign(cat = ['LOW']*400 + ['MID']*400 + ['HIGH']*400 )

答案 1 :(得分:0)

在这里回答熊猫是否可以改善的问题: documentation 中明确指出了loc在做什么:

  

.loc主要基于标签,但也可以与布尔数组一起使用。找不到项目时,.loc将引发KeyError。

因此-400根本不是索引中的标签。因此,行为符合预期。

人们经常想要的是基于iloc的行访问和基于loc的列访问的访问器。但是为此,.get_loc函数开始发挥作用。

您还可以使用不推荐使用的.ix-索引器。但是,其行为引起了一些混乱。她使用.loc.iloc访问器here的示例和方法。 从本质上讲,@ Jezrael的解决方案也在上面的链接中找到。

总结:熊猫已经为您的问题提供了解决方案,但它使用户感到困惑。因此,为了提供更一致的API,决定将来删除该功能