【问题标题】:Why do loc and iloc work differently for slicing rows of a pandas DataFrame?为什么 loc 和 iloc 在对 pandas DataFrame 的行进行切片时工作方式不同?
【发布时间】:2018-07-08 14:23:25
【问题描述】:

我想要一个 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。这是 pandas 可以改进的地方吗?

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()

【问题讨论】:

  • 你也只能使用.iloc

标签: python pandas


【解决方案1】:

如果想按iloc 的位置选择,请使用get_loccat 的位置 - 需要索引和列的位置:

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 )

【讨论】:

  • 另一种方式:df.assign(cat = ['LOW']*400 + ['MID']*400 + ['HIGH']*400 )
  • @jezraels,我认为,您应该将第一个解决方案更改为仅使用 .iloc。我认为使用这两个访问器是困扰 OP
  • 这很好,我喜欢使用 np.array + 重复的那个,谢谢!
【解决方案2】:

在这里回答熊猫是否可以改进的问题: 我 documentation 清楚地说明了 loc 在做什么:

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

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

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

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

总结一下:Pandas 为您的问题提供了解决方案,但它让用户感到困惑。因此,为了提供更一致的 API,我们决定在未来移除该功能

【讨论】:

    猜你喜欢
    • 2021-08-29
    • 1970-01-01
    • 2016-10-21
    • 1970-01-01
    • 2019-07-15
    • 2018-02-20
    • 2017-05-21
    • 2018-02-08
    • 1970-01-01
    相关资源
    最近更新 更多