2014-01-08 59 views
1

我有兩個有關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列設置爲'3'。但df.iloc[5]['B'] = 'three'不這樣做。我檢查了manual,但它不包括如何更改按位置訪問的特定單元值。

如果我正在按行名訪問,我可以這樣做:df.loc[5,'B'] = 'three'但我不知道索引訪問等價物是什麼。

P.S. Link1link2是我第二個問題的相關答案。但是,他們不回答我的問題。

回答

5

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的行...所以你不妨考慮一下製作你的'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的第五元素的B列設置爲「3」。但df.iloc [5] ['B'] ='三'不會這樣做。我檢查了手冊,但沒有介紹如何更改按位置訪問的特定單元格值。

傑夫已經回答了這個...

+0

gr8!當我讀到這個問題時,我認爲我的答案更有意義! – Jeff

2
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衛理用於重置指數, 這就是我想你想)

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] 
+0

謝謝傑夫。那麼對我的問題1和2的答案有什麼想法? – Rhubarb