【问题标题】:Pandas: Index updating and changing value accessed by locationPandas:按位置访问的索引更新和更改值
【发布时间】:2014-01-26 15:18:46
【问题描述】:

我有两个关于 Python Pandas 数据帧的索引相关问题。

import pandas as pd
import numpy as np
df = pd.DataFrame({'id' : range(1,9),
                'B' : ['one', 'one', 'two', 'three',
                       'two', 'three', 'one', 'two'],
                'amount' : np.random.randn(8)})

df = df.ix[df.B != 'three'] # remove where B = three
df.index
>>  Int64Index([0, 1, 2, 4, 6, 7], dtype=int64) # the original index is preserved.

1)我不明白为什么我修改数据框后索引没有自动更新。有没有办法在修改数据框时自动更新索引?如果没有,最有效的手动方式是什么?

2) 我希望能够将df 的第5 个元素的B 列设置为“三”。但是df.iloc[5]['B'] = 'three' 不会那样做。我检查了manual,但它没有介绍如何更改按位置访问的特定单元格值。

如果我按行名访问,我可以这样做:df.loc[5,'B'] = 'three',但我不知道索引访问等效项是什么。

附: Link1link2 是我第二个问题的相关答案。但是,他们没有回答我的问题。

【问题讨论】:

    标签: python indexing pandas dataframe


    【解决方案1】:
    In [5]: df = pd.DataFrame({'id' : range(1,9),
       ...:                 'B' : ['one', 'one', 'two', 'three',
       ...:                        'two', 'three', 'one', 'two'],
       ...:                 'amount' : np.random.randn(8)})
    
    In [6]: df
    Out[6]: 
           B    amount  id
    0    one -1.236735   1
    1    one -0.427070   2
    2    two -2.330888   3
    3  three -0.654062   4
    4    two  0.587660   5
    5  three -0.719589   6
    6    one  0.860739   7
    7    two -2.041390   8
    
    [8 rows x 3 columns]
    

    您的问题 1)您上面的代码是正确的(请参阅@Briford Wylie 重置索引, 这就是我认为你想要的)

    In [7]: df.ix[df.B!='three']
    Out[7]: 
         B    amount  id
    0  one -1.236735   1
    1  one -0.427070   2
    2  two -2.330888   3
    4  two  0.587660   5
    6  one  0.860739   7
    7  two -2.041390   8
    
    [6 rows x 3 columns]
    
    In [8]: df = df.ix[df.B!='three']
    
    In [9]: df.index
    Out[9]: Int64Index([0, 1, 2, 4, 6, 7], dtype='int64')
    
    In [10]: df.iloc[5]
    Out[10]: 
    B             two
    amount   -2.04139
    id              8
    Name: 7, dtype: object
    

    问题2):

    您正在尝试设置副本;在 0.13 中,这将引发/警告。见here

    In [11]: df.iloc[5]['B'] = 5
    /usr/local/bin/ipython:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame.
    
    In [24]: df.iloc[5,df.columns.get_indexer(['B'])] = 'foo'
    
    In [25]: df
    Out[25]: 
         B    amount  id
    0  one -1.236735   1
    1  one -0.427070   2
    2  two -2.330888   3
    4  two  0.587660   5
    6  one  0.860739   7
    7  foo -2.041390   8
    
    [6 rows x 3 columns]
    

    您也可以这样做。这不是设置副本,因为它选择了一个系列(这就是df['B'],所以可以直接设置它

    In [30]: df['B'].iloc[5] = 5
    
    In [31]: df
    Out[31]: 
         B    amount  id
    0  one -1.236735   1
    1  one -0.427070   2
    2  two -2.330888   3
    4  two  0.587660   5
    6  one  0.860739   7
    7    5 -2.041390   8
    
    [6 rows x 3 columns]
    

    【讨论】:

    • 谢谢杰夫。那么对我的问题 1 和 2 的答案有什么想法吗?
    【解决方案2】:

    1) 我不明白为什么我修改数据框后索引没有自动更新。

    如果您想在删除/添加行后重置索引,您可以这样做:

    df = df[df.B != 'three'] # remove where B = three
    df.reset_index(drop=True)
    
           B    amount  id
    0    one    -1.176137    1
    1    one     0.434470    2
    2    two    -0.887526    3
    3    two     0.126969    5
    4    one     0.090442    7
    5    two    -1.511353    8
    

    索引旨在标记/标记/标识一行...因此您可能会考虑将“id”列设为索引,然后您会发现 Pandas 在删除时不会“自动更新”索引行。

    df.set_index('id')
    
           B    amount
    id      
    1    one    -0.410671
    2    one     0.092931
    3    two    -0.100324
    4    three   0.322580
    5    two    -0.546932
    6    three  -2.018198
    7    one    -0.459551
    8    two     1.254597
    

    2) 我希望能够将 df 的第 5 个元素的 B 列设置为“三”。但是 df.iloc[5]['B'] = 'three' 并没有这样做。我查看了手册,但它没有介绍如何更改按位置访问的特定单元格值。

    Jeff 已经回答了这个问题...

    【讨论】:

    • gr8!当我阅读问题时,我认为我的答案更有意义!
    猜你喜欢
    • 2014-09-04
    • 2021-08-28
    • 2013-02-21
    • 2021-09-18
    • 2019-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-10
    相关资源
    最近更新 更多