2016-11-04 26 views
5

Give sau dfcột mới trong gấu trúc - thêm hàng loạt để dataframe bằng cách áp dụng một danh sách groupby

Id other concat 
0 A  z  1 
1 A  y  2 
2 B  x  3 
3 B  w  4 
4 B  v  5 
5 B  u  6 

Tôi muốn các kết quả với new cột với các giá trị nhóm dạng danh sách

Id other concat   new 
0 A  z  1  [1, 2] 
1 A  y  2  [1, 2] 
2 B  x  3 [3, 4, 5, 6] 
3 B  w  4 [3, 4, 5, 6] 
4 B  v  5 [3, 4, 5, 6] 
5 B  u  6 [3, 4, 5, 6] 

này tương tự cho những câu hỏi sau:

grouping rows in list in pandas groupby

Replicating GROUP_CONCAT for pandas.DataFrame

Tuy nhiên, nó là áp dụng các nhóm bạn nhận được từ df.groupby('Id')['concat'].apply(list), mà là một Series kích thước nhỏ hơn so với dataframe, đến dataframe gốc.

Tôi đã thử đoạn code dưới đây, nhưng nó không áp dụng điều này để các dataframe:

import pandas as pd 
df = pd.DataFrame({'Id':['A','A','B','B','B','C'], 'other':['z','y','x','w','v','u'], 'concat':[1,2,5,5,4,6]}) 
df.groupby('Id')['concat'].apply(list) 

Tôi biết rằng transform có thể được sử dụng để áp dụng các nhóm để dataframes, nhưng nó không hoạt động trong trường hợp này.

>>> df['new_col'] = df.groupby('Id')['concat'].transform(list) 
>>> df 
    Id concat other new_col 
0 A  1  z  1 
1 A  2  y  2 
2 B  5  x  5 
3 B  5  w  5 
4 B  4  v  4 
5 C  6  u  6 
>>> df['new_col'] = df.groupby('Id')['concat'].apply(list) 
>>> df 
    Id concat other new_col 
0 A  1  z  NaN 
1 A  2  y  NaN 
2 B  5  x  NaN 
3 B  5  w  NaN 
4 B  4  v  NaN 
5 C  6  u  NaN 

Trả lời

4

groupby với join

df.join(df.groupby('Id').concat.apply(list).to_frame('new'), on='Id') 

enter image description here

3

giải pháp Ít thanh lịch (.. và chậm hơn), nhưng để cho nó có mặt ở đây cũng giống như một sự thay thế.

def func(gr): 
    gr['new'] = [list(gr.concat)] * len(gr.index) 
    return gr 
df.groupby('Id').apply(func) 

%timeit df.groupby('Id').apply(func) 
100 loops, best of 3: 4.18 ms per loop 

%timeit df.join(df.groupby('Id').concat.apply(list).to_frame('new'), on='Id') 
1000 loops, best of 3: 1.69 ms per loop 
1

Sử dụng transform với [x.tolist()] hoặc [x.values]

In [1396]: df.groupby('Id')['concat'].transform(lambda x: [x.tolist()]) 
Out[1396]: 
0   [1, 2] 
1   [1, 2] 
2 [3, 4, 5, 6] 
3 [3, 4, 5, 6] 
4 [3, 4, 5, 6] 
5 [3, 4, 5, 6] 
Name: concat, dtype: object 

In [1397]: df['new'] = df.groupby('Id')['concat'].transform(lambda x: [x.tolist()]) 

In [1398]: df 
Out[1398]: 
    Id other concat   new 
0 A  z  1  [1, 2] 
1 A  y  2  [1, 2] 
2 B  x  3 [3, 4, 5, 6] 
3 B  w  4 [3, 4, 5, 6] 
4 B  v  5 [3, 4, 5, 6] 
5 B  u  6 [3, 4, 5, 6] 
Các vấn đề liên quan