2016-06-06 1 views
1

Я хотел бы добавить столбец в dataframe pandas, где это значение является добавочным значением, начиная со значения из другого столбца. Например, скажем, у меня есть следующий фрейм.pandas get counts on previous column

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 

Есть ли какая-нибудь функция pandas, которая вернет серию, увеличивающую значение для каждой группы? другими словами 'a' начнет с 1, 'b' с 5 и 'c' с 10. Серия выход будет (1, 2, 5, 10, 11, 12) поэтому он может быть добавлен к исходному dataframe так:

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 (диапазон (начало, длина + старт)) 'вместо' z.append ... ' – andrew

ответ

3

попробовать:

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

Это хорошее решение, однако оно не распространяется на более сложные случаи. Я обновил квест, чтобы уточнить, что я имею в виду. Решение в моем вопросе тоже не учитывает, но я зациклился на том, как это сделать. – johnchase

+0

На основании ваших предложений это 'df ['z'] = df.groupby ('x'). Apply (lambda x: x ['y'] + range (len (x))). Значения, кажется, выполняют то, что я пытался сделать. – 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] 

EDIT: от более быстрого преобразования, вы можете использовать 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'S:

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)