【问题标题】:Select and modify a slice in pandas dataframe by integer index通过整数索引选择和修改 pandas 数据框中的切片
【发布时间】:2017-11-24 00:09:12
【问题描述】:

我有一个如下的数据框:

df = pd.DataFrame([[1,2],[10,20],[10,2],[1,40]],columns = ['a','b'])
    a   b
0   1   2
1   10  20
2   10  2
3   1   40

我要选择a == 1所在的b列,下面是经典的选择:

df[df.a == 1].b
    a   b
0   1   2
3   1   40

然后我想选择这个子数据帧的第 i 行,它不是索引为 i 的行。还有几种方法,如下所示:

df[df.a == 1].b.iloc[[1]]
Output: 
3    40
Name: b, dtype: int64

到目前为止一切顺利。问题是当我尝试修改我得到的值时,实际上这种选择方法会产生数据帧切片的副本,而不是对象本身。因此我无法就地修改它。

test[test.a == 1].b.iloc[[1]] = 3
SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame

我不知道“复制”问题出在哪一部分,因为以下两个产生了相同的问题:

test.iloc[[3]].b = 3
test[test.a == 1].b = 3

所以我的问题是:如何通过掩码选择(有条件地在 a 列值上)和行选择(通过子数据框中行的排名,而不是其索引值)来更改值)?

【问题讨论】:

    标签: python pandas indexing


    【解决方案1】:

    loc与布尔掩码一起使用并直接向上传递索引:

    In[178]:
    df.loc[df.loc[df['a'] == 1,'b'].index[1], 'b'] = 3
    df
    
    Out[178]: 
        a   b
    0   1   2
    1  10  20
    2  10   2
    3   1   3
    

    所以这里我们使用df['a'] == 1屏蔽df,这将返回一个布尔数组,我们屏蔽df并只选择列'b'

    In[179]:
    df.loc[df['a'] == 1,'b']
    
    Out[179]: 
    0    2
    3    40
    Name: b, dtype: int64
    

    然后直接下标索引:

    In[180]:
    df.loc[df['a'] == 1,'b'].index[1]
    
    Out[180]: 3
    

    然后我们可以将此索引标签传递回顶级loc

    这个test[test.a == 1].b.iloc[[1]] = 3chained indexing,这就是发出警告的原因。

    【讨论】:

    • 要摆脱的事情是不要链接lociloc 调用,您应该合成掩码,或者如果您可以直接计算索引标签,那么您可以将其传递给loc
    猜你喜欢
    • 2017-01-13
    • 2021-11-08
    • 2018-12-25
    • 2014-07-04
    • 2017-08-11
    • 1970-01-01
    • 1970-01-01
    • 2016-10-16
    • 1970-01-01
    相关资源
    最近更新 更多