เชื่อมต่อสตริงจากหลายแถวโดยใช้ Pandas groupby


92

ฉันต้องการรวมหลาย ๆ สตริงในดาต้าเฟรมโดยยึดตาม groupedby ใน Pandas

นี่คือรหัสของฉันจนถึงตอนนี้:

import pandas as pd
from io import StringIO

data = StringIO("""
"name1","hej","2014-11-01"
"name1","du","2014-11-02"
"name1","aj","2014-12-01"
"name1","oj","2014-12-02"
"name2","fin","2014-11-01"
"name2","katt","2014-11-02"
"name2","mycket","2014-12-01"
"name2","lite","2014-12-01"
""")

# load string as stream into dataframe
df = pd.read_csv(data,header=0, names=["name","text","date"],parse_dates=[2])

# add column with month
df["month"] = df["date"].apply(lambda x: x.month)

ฉันต้องการให้ผลลัพธ์สุดท้ายมีลักษณะดังนี้:

ป้อนคำอธิบายภาพที่นี่

ฉันไม่เข้าใจว่าฉันจะใช้ groupby ได้อย่างไรและใช้การเรียงต่อกันของสตริงในคอลัมน์ "text" ความช่วยเหลือใด ๆ ที่ชื่นชม!

คำตอบ:


161

คุณสามารถจัดกลุ่มตามคอลัมน์'name'และ'month'จากนั้นเรียกtransformซึ่งจะส่งคืนข้อมูลที่สอดคล้องกับ df เดิมและใช้แลมบ์ดาที่เราjoinป้อนข้อความ:

In [119]:

df['text'] = df[['name','text','month']].groupby(['name','month'])['text'].transform(lambda x: ','.join(x))
df[['name','text','month']].drop_duplicates()
Out[119]:
    name         text  month
0  name1       hej,du     11
2  name1        aj,oj     12
4  name2     fin,katt     11
6  name2  mycket,lite     12

ฉันย่อย df ดั้งเดิมโดยส่งรายการคอลัมน์ที่น่าสนใจdf[['name','text','month']]ที่นี่แล้วโทรdrop_duplicates

แก้ไขจริงๆแล้วฉันสามารถโทรapplyแล้วreset_index:

In [124]:

df.groupby(['name','month'])['text'].apply(lambda x: ','.join(x)).reset_index()

Out[124]:
    name  month         text
0  name1     11       hej,du
1  name1     12        aj,oj
2  name2     11     fin,katt
3  name2     12  mycket,lite

อัพเดต

lambdaไม่จำเป็นที่นี่:

In[38]:
df.groupby(['name','month'])['text'].apply(','.join).reset_index()

Out[38]: 
    name  month         text
0  name1     11           du
1  name1     12        aj,oj
2  name2     11     fin,katt
3  name2     12  mycket,lite

1
ในpandas < 1.0, .drop_duplicates()ละเว้นดัชนีซึ่งอาจให้ผลลัพธ์ที่ไม่คาดคิด คุณสามารถหลีกเลี่ยงสิ่งนี้ได้โดยใช้.agg(lambda x: ','.join(x))แทน.transform().drop_duplicates().
Matthias Fripp

เรียบร้อยและไม่ซับซ้อน เฟลกซิเบิลได้ในที่สุด
Raghavan vmvs

drop_duplicates()อาจไม่ทำงานถ้าคุณไม่รวมพารามิเตอร์drop_duplicates(inplace=True)หรือเพียงแค่เขียนบรรทัดของโค้ดใหม่เป็น df = df[['name','text','month']].drop_duplicates()
IAmBotmaker

44

เราสามารถgroupBy 'ชื่อ' และ 'เดือน' คอลัมน์แล้วโทร AGG () ฟังก์ชั่นของหมีแพนด้าวัตถุ DataFrame

ฟังก์ชันการรวมที่จัดเตรียมโดยฟังก์ชัน agg () ช่วยให้สามารถคำนวณสถิติหลายรายการต่อกลุ่มในการคำนวณเดียว

df.groupby(['name', 'month'], as_index = False).agg({'text': ' '.join})

ป้อนคำอธิบายภาพที่นี่


27

คำตอบของ EdChum ช่วยให้คุณมีความยืดหยุ่นอย่างมาก แต่ถ้าคุณเพียงแค่ต้องการเชื่อมสตริงเข้ากับคอลัมน์ของรายการวัตถุคุณยังสามารถ:

output_series = df.groupby(['name','month'])['text'].apply(list)


คุณช่วยฉันประหยัดเวลาได้มาก ขอบคุณ. นี่เป็นวิธีที่ดีที่สุดในการรวบรวมรายการตามลำดับเวลาของการลงทะเบียน / รหัสผู้ใช้เป็น 'กลุ่มประชากรตามรุ่น' ที่ฉันรู้จัก ขอบคุณอีกครั้ง.
Alex Fedotov

5

สำหรับฉันวิธีแก้ปัญหาข้างต้นนั้นใกล้เคียง แต่เพิ่ม / n และ dtype: object ที่ไม่ต้องการดังนั้นนี่คือเวอร์ชันที่แก้ไข:

df.groupby(['name', 'month'])['text'].apply(lambda text: ''.join(text.to_string(index=False))).str.replace('(\\n)', '').reset_index()
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.