2016-06-06 27 views
1

我想將列添加到熊貓數據框中,其中值是以另一列中的值開始的遞增值。比如說我有以下數據框。熊貓根據以前的列獲得計數

df = pd.DataFrame([['a', 1], ['a', 1], ['b', 5], ['c', 10], ['c', 10], ['c', 10]], columns=['x', 'y']) 
df 

    x y 
0 a 1 
1 a 1 
2 b 5 
3 c 10 
4 c 10 
5 c 10 

是否有一些熊貓的功能會返回一個系列,每個組的增加值?換句話說'a'將以1,'b'5'c'10開始。輸出系列將(1, 2, 5, 10, 11, 12)因此它可以被添加到原始數據幀像這樣:

x y z 
0 a 1 1 
1 a 1 2 
2 b 5 5 
3 c 10 10 
4 c 10 11 
5 c 10 12 

我試過如下:

z = [] 
for start, length in zip(df.y.unique(), df.groupby('x').agg('count')['y']): 
    z.append(list(range(start, length + start))) 
np.array(z).flatten() 
z 

[[1, 2], [5], [10, 11, 12]] 

這並不完全得到我需要什麼,我不知道爲什麼陣列不會變平坦,而且看似簡單的任務似乎過於複雜。

編輯: 該解決方案應該是可擴展到更復雜的dataframes爲好,例如:

df = pd.DataFrame([['a', 1], ['b', 5], ['c', 10], ['d', 5]], columns=['x', 'y']) 
df = df.append([df]*(50),ignore_index=True) 

當兩者'a''b'值列「X」是eqaul至5。在這兩個的實例計數應在5

+0

使用'ž .extend(range(start,length + start))'而不是'z.append ...' – andrew

回答

3

嘗試啓動:

df['z'] = df.y + df.groupby('y').apply(lambda df: pd.Series(range(len(df)))).values 
+0

這是一個很好的解決方案,但它不能擴展到更復雜的情況。我更新了questiion以澄清我的意思。我的問題的解決方案也沒有考慮到這一點,但我堅持如何實現它 – johnchase

+0

根據你的建議,這個'df ['z'] = df.groupby('x')。apply(lambda x: x ['y'] + range(len(x)))。values'似乎完成了我想要做的事情。 – johnchase

1

雖然不是熊貓相關的答案,走出的嵌套列表,並將其展平,你可以使用一個簡單的列表理解來解釋你當前擁有的z。

>>>z = [[1, 2], [5], [10, 11, 12]] 
>>>z_flat = [num for sublist in z for num in sublist]) 
>>>z_flat 
[1, 2, 5, 10, 11, 12] 

編輯:對於一個更快的轉換,你可以使用itertools.chain()

In [5]: import itertools 

In [6]: z 
Out[6]: [[1, 2], [5], [10, 11, 12]] 

In [7]: merged = list(itertools.chain(*z)) 

In [8]: merged 
Out[8]: [1, 2, 5, 10, 11, 12] 
1

這裏是一個醜陋的方式方法相比,@ piRSquared的:

def func(group): 
    x = group['y'].head(1).values 
    l = [] 
    for i in range(len(group)): 
     l.append(x+i) 
    return pd.Series(l, name='z') 

x = df.groupby('x').apply(func).reset_index().drop('level_1', axis=1) 
x['z'] = x['z'].apply(lambda x: x[0]) 
pd.concat([df, x['z']], axis=1)