2017-07-25 24 views
0

我有以下數據框:熊貓:第一轉換值組np.nan

df = pd.DataFrame({'series1':['A','A','A','A','B','B','B','C','C','C','C'], 
        'series2':[0,1,10,99,-9,9,0,10,20,10,10]}) 
    series1 series2 
0  A  0.0 
1  A  1.0 
2  A  10.0 
3  A  99.0 
4  B  -9.0 
5  B  9.0 
6  B  0.0 
7  C  10.0 
8  C  20.0 
9  C  10.0 
10  C  10.0 

我想要什麼:

df2 = pd.DataFrame({'series1':['A','A','A','A','B','B','B','C','C','C','C'], 
        'series2':[np.nan,1,10,99,np.nan,9,0,np.nan,20,10,10]}) 
    series1 series2 
0  A  NaN 
1  A  1.0 
2  A  10.0 
3  A  99.0 
4  B  NaN 
5  B  9.0 
6  B  0.0 
7  C  NaN 
8  C  20.0 
9  C  10.0 
10  C  10.0 

我有一種感覺,這也許能夠通過完成用熊貓.groupby功能:

df.groupby('series1').first() 
     series2 
series1   
A    0 
B    -9 
C    10 

這給我,我要轉換爲NaN的意見,但我想不出一種輕鬆地在原始DataFrame中替換它的方法。

這只是一個簡單的例子,我正在使用的實際數據幀具有> 8,000,000個觀察值。

回答

3

有可能是一個滑頭的方式來做到這一點,但每個組中的第一個元素是該組中的第0個元素,並且cumcount對每個組內的元素進行編號。所以:

In [19]: df.loc[df.groupby('series1').cumcount() == 0, 'series2'] = np.nan 

In [20]: df 
Out[20]: 
    series1 series2 
0  A  NaN 
1  A  1.0 
2  A  10.0 
3  A  99.0 
4  B  NaN 
5  B  9.0 
6  B  0.0 
7  C  NaN 
8  C  20.0 
9  C  10.0 
10  C  10.0 
3

你想通過轉移下來,並與自己進行比較來定位series1間斷:

df.loc[df['series1'].shift() != df['series1'], 'series2'] = np.nan 
2

另一種選擇通過移動列:

df['series2'] = df.groupby('series1').series2.transform(lambda x: x.shift(-1).shift()) 

df 
# series1 series2 
#0  A  NaN 
#1  A  1.0 
#2  A  10.0 
#3  A  99.0 
#4  B  NaN 
#5  B  9.0 
#6  B  0.0 
#7  C  NaN 
#8  C  20.0 
#9  C  10.0 
#10  C  10.0 
+0

!!!!!不錯的解決方案~~~ – Wen

+0

@Wen謝謝! ^^ – Psidom

2

,也可以使用headfirstnth全部歸還相同的結果通過索引切片。

df.loc[df.groupby('series1',as_index=False).head(1).index,'series2'] = np.nan 
    #df.loc[df.groupby('series1',as_index=False).first().index,'series2'] = np.nan 
    #df.loc[df.groupby('series1',as_index=False).nth(1).index,'series2'] = np.nan