Python 为什么loc和iloc对数据帧的行进行切片的工作方式不同?
我想要一个数据帧,其中一列(称为“cat”)的顶行的值为“LOW”,帧的中间和底部的值为“mid”和“HI”。因此,对于1200行的帧,Python 为什么loc和iloc对数据帧的行进行切片的工作方式不同?,python,pandas,Python,Pandas,我想要一个数据帧,其中一列(称为“cat”)的顶行的值为“LOW”,帧的中间和底部的值为“mid”和“HI”。因此,对于1200行的帧,cat列的值计数应导致: LOW 400 MID 400 HI 400 这应该很容易。但是,显然不是真的。我试图使用df.loc[-400:,[“cat”]]=“HI” 但是,这种方法确实适用于最上面的行:df.loc[:399,[“cat”]]=“LOW” 下面的示例显示了一个工作示例,请注意它需要loc和iloc。这是熊猫可以改进的地方
cat
列的值计数应导致:
LOW 400
MID 400
HI 400
这应该很容易。但是,显然不是真的。我试图使用df.loc[-400:,[“cat”]]=“HI”
但是,这种方法确实适用于最上面的行:df.loc[:399,[“cat”]]=“LOW”
下面的示例显示了一个工作示例,请注意它需要loc
和iloc
。这是熊猫可以改进的地方吗
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()
用于列的位置cat
如果希望通过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个值的另一种方法是使用或通过重复列表设置值:
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 )
在这里回答熊猫是否可以提高的问题: 我清楚地说明了loc正在做什么: .loc主要基于标签,但也可与布尔数组一起使用。当找不到项目时,loc将引发KeyError 所以-400并不是索引中的标签。因此,行为符合预期 人们通常需要的是基于iloc的行访问和基于loc的列访问的访问器和访问器。但是对于这一点,
.get\u loc
-功能开始发挥作用
您还可以使用不推荐使用的.ix
-索引器。然而,它的行为引起了一些混乱。她介绍了使用.loc
和.iloc
访问器的示例和方法。
基本上,@Jezrael的解决方案也可以在上面的链接中找到
总而言之:Pandas已经为您的问题找到了解决方案,但它让用户感到困惑。因此,为了提供更一致的API,决定在将来以另一种方式删除该功能:
df.assign(cat=['LOW']*400+['MID']*400+['HIGH']*400)
@jezraels,我认为,您应该将第一个解决方案改为只使用.iloc
。我认为使用这两个访问器是困扰OPS的原因。这非常好,我喜欢使用np.array+repeat的访问器,谢谢!您也只能使用.iloc