Nhóm gấu trúc theo kết quả cho các cột


8

Tôi có khung dữ liệu như thế này:

x = pd.DataFrame({
    'audio': ['audio1', 'audio1', 'audio2', 'audio2', 'audio3', 'audio3'],
    'text': ['text1', 'text2', 'text3', 'text4', 'text5', 'text6'],
    'login': ['operator1', 'operator2', 'operator3', 'operator4', 'operator5', 'operator6'] 
})

Tôi đang cố gắng tổng hợp nó như thế này:

x1 = x.groupby('audio')['text'].agg(
    [
    ('text1', lambda x : x.iat[0]),
    ('text2', lambda x : x.iat[1]),
    ('leven', lambda x: Levenshtein.distance(x.iat[0], x.iat[1])) #some function works with grouped text
    ]
).reset_index()

và nó hoạt động nhưng tôi cũng cần thêm thông tin đăng nhập được nhóm vào hàng, để tạo hàng như thế này:

audio, text1, text2, leven, login1, login2

Tôi đã thử một cái gì đó như lambda x : x.ait[0, 1]nhưng nó không hoạt động


Là dữ liệu luôn được sắp xếp và theo cặp hai hàng thuộc về nhau?
Darkonaut

Câu trả lời:


6

Nhìn vào khung dữ liệu của bạn, tôi nghĩ đến việc xoay khung dữ liệu, dưới đây là cách tiếp cận của tôi để sử dụng groupby().cumcount()unstackvới một số định dạng cột để tạo một khung dữ liệu được chia nhỏ.

Tùy chọn 1: Sau đó, bạn có thể sử dụng df.applyđể áp dụng chức năng

m = x.assign(k=x.groupby('audio').cumcount().add(1)).set_index(['audio','k']).unstack()
m.columns=[f"{a}{b}" for a,b in m.columns]
m = m.assign(leven=m.apply(lambda x: 
              Levenshtein.distance(x['text1'],x['text2']),1)).reset_index()

    audio  text1  text2     login1     login2  leven
0  audio1  text1  text2  operator1  operator2      1
1  audio2  text3  text4  operator3  operator4      1
2  audio3  text5  text6  operator5  operator6      1

Tùy chọn 2: ( Tôi thích cái này )

Bạn cũng có thể sử dụng cách hiểu danh sách để làm tương tự, chỉ cần thay thế dòng cuối cùng bằng:

m = x.assign(k=x.groupby('audio').cumcount().add(1)).set_index(['audio','k']).unstack()
m.columns=[f"{a}{b}" for a,b in m.columns]
m = m.assign(leven=[Levenshtein.distance(a,b) for 
               a,b in zip(m['text1'],m['text2'])]).reset_index()

    audio  text1  text2     login1     login2  leven
0  audio1  text1  text2  operator1  operator2      1
1  audio2  text3  text4  operator3  operator4      1
2  audio3  text5  text6  operator5  operator6      1

Tùy chọn 3:

Nếu vị trí của levencột là quan trọng, bạn có thể sử dụng df.insert:

m=x.assign(k=x.groupby('audio').cumcount().add(1)).set_index(['audio','k']).unstack()
m.columns=[f"{a}{b}" for a,b in m.columns]
m.insert(2,'leven',[Levenshtein.distance(a,b) for a,b in zip(m['text1'],m['text2'])])
m=m.reset_index()

    audio  text1  text2  leven     login1     login2
0  audio1  text1  text2      1  operator1  operator2
1  audio2  text3  text4      1  operator3  operator4
2  audio3  text5  text6      1  operator5  operator6

1
thật tuyệt, bạn có thể muốn xem xét FuzzyWuzzyđể sử dụng Thuật toán khoảng cách Levenshtein
Datanovice

@Datanovice yep, tuy nhiên tôi tin rằng OP sử dụng cái này ở đây. bất kể func nào cũng hoạt động :)
anky

1
Trả lời hay, tôi nghĩ bạn sẽ nhận được +50;)
jezrael

2

Đây có phải là những gì bạn đang tìm kiếm:

x1 = x.groupby('audio',)['login'].agg(
     [
     ('operator1', lambda x : x.iat[0]),
     ('operator2', lambda x : x.iat[1]),
     ('leven', lambda x: Levenshtein.distance(x.iat[0], x.iat[1])) #some function works with grouped text
     ]
 ).reset_index()

 x2 = x.groupby('audio',)['text'].agg(
     [
     ('text1', lambda x : x.iat[0]),
     ('text2', lambda x : x.iat[1]),
     ('leven', lambda x: Levenshtein.distance(x.iat[0], x.iat[1])) #some function works with grouped text
     ]
 ).reset_index()

x1.merge(x2)

    audio  operator1  operator2  leven  text1  text2
0  audio1  operator1  operator2      1  text1  text2
1  audio2  operator3  operator4      1  text3  text4
2  audio3  operator5  operator6      1  text5  text6

0

Giải pháp này hoạt động rất tốt khi bạn có nhiều cột, nó tự động mở rộng chúng để bạn không phải liệt kê chúng theo cách thủ công.

x = pd.DataFrame({
    'audio': ['audio1', 'audio1', 'audio2', 'audio2', 'audio3', 'audio3'],
    'text': ['text1', 'text2', 'text3', 'text4', 'text5', 'text6'],
    'login': ['operator1', 'operator2', 'operator3', 'operator4', 'operator5', 'operator6'] 
})


text = x.groupby(['audio']).agg(list)['text'].apply(pd.Series).rename(columns=lambda x: f'text{x+1}')

login = x.groupby(['audio']).agg(list)['login'].apply(pd.Series).rename(columns=lambda x: f'login{x+1}')

text['leven'] = df.apply(lambda x: Levenshtein.distance(x.text1, x.text2), axis=1) 

df = text.assign(**login)

        text1  text2  leven     login1     login2
audio                                            
audio1  text1  text2      1  operator1  operator2
audio2  text3  text4      1  operator3  operator4
audio3  text5  text6      1  operator5  operator6

0

Bạn chỉ có thể sửa đổi aggbiểu thức của bạn như thế này:

x1 = x.groupby('audio').agg({'text':[
    ('text1', lambda x : x.iat[0]),
    ('text2', lambda x : x.iat[1])
    ('leven', lambda x: Levenshtein.distance(x.iat[0], x.iat[1])) #some function works with grouped text
    ],
    'login': [
    ('login1', lambda x : x.iat[0]),
    ('login2', lambda x : x.iat[1])]
    }
).droplevel(0,axis=1).reset_index()
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.