TL; DR เวอร์ชัน:
สำหรับกรณีง่าย ๆ ของ:
- ฉันมีคอลัมน์ข้อความพร้อมตัวคั่นและฉันต้องการสองคอลัมน์
ทางออกที่ง่ายที่สุดคือ:
df['A'], df['B'] = df['AB'].str.split(' ', 1).str
หรือคุณสามารถสร้างสร้าง DataFrame ด้วยหนึ่งคอลัมน์สำหรับแต่ละรายการของการแบ่งโดยอัตโนมัติด้วย:
df['AB'].str.split(' ', 1, expand=True)
คุณต้องใช้expand=True
ถ้าสตริงของคุณมีจำนวนของการแบ่งที่ไม่สม่ำเสมอและคุณต้องการNone
แทนที่ค่าที่หายไป
สังเกตว่าไม่ว่าในกรณีใด.tolist()
วิธีการนี้ไม่จำเป็น zip()
ไม่เป็น
ในรายละเอียด:
คำตอบของ Andy Haydenนั้นยอดเยี่ยมที่สุดในการแสดงพลังของstr.extract()
วิธีการ
แต่สำหรับการแยกง่ายกว่าคั่นที่รู้จักกัน (เช่นแยกจากรอยขีดข่วนหรือแยกโดยช่องว่าง) ที่.str.split()
เป็นวิธีการที่เพียงพอที่1 มันทำงานบนคอลัมน์ (Series) ของสตริงและส่งกลับคอลัมน์ (Series) ของรายการ:
>>> import pandas as pd
>>> df = pd.DataFrame({'AB': ['A1-B1', 'A2-B2']})
>>> df
AB
0 A1-B1
1 A2-B2
>>> df['AB_split'] = df['AB'].str.split('-')
>>> df
AB AB_split
0 A1-B1 [A1, B1]
1 A2-B2 [A2, B2]
1: หากคุณไม่แน่ใจว่าสิ่งที่กำลังสองพารามิเตอร์แรกของการ.str.split()
ทำผมขอแนะนำเอกสารสำหรับรุ่นหลามธรรมดาของวิธีการ
แต่คุณจะไปจาก:
- คอลัมน์ที่มีรายการองค์ประกอบสององค์ประกอบ
ถึง:
- สองคอลัมน์แต่ละรายการมีองค์ประกอบที่เกี่ยวข้องของรายการหรือไม่
เราต้องพิจารณา.str
คุณสมบัติของคอลัมน์ให้ละเอียดยิ่งขึ้น
มันเป็นวัตถุมหัศจรรย์ที่ใช้เพื่อรวบรวมวิธีการที่ปฏิบัติต่อแต่ละองค์ประกอบในคอลัมน์เป็นสตริงจากนั้นใช้วิธีการที่เกี่ยวข้องในแต่ละองค์ประกอบให้มีประสิทธิภาพมากที่สุด:
>>> upper_lower_df = pd.DataFrame({"U": ["A", "B", "C"]})
>>> upper_lower_df
U
0 A
1 B
2 C
>>> upper_lower_df["L"] = upper_lower_df["U"].str.lower()
>>> upper_lower_df
U L
0 A a
1 B b
2 C c
แต่มันยังมีอินเทอร์เฟซ "การจัดทำดัชนี" สำหรับการรับแต่ละองค์ประกอบของสตริงตามดัชนี:
>>> df['AB'].str[0]
0 A
1 A
Name: AB, dtype: object
>>> df['AB'].str[1]
0 1
1 2
Name: AB, dtype: object
แน่นอนอินเทอร์เฟซการจัดทำดัชนีของ.str
นี้ไม่สนใจจริง ๆ ว่าองค์ประกอบแต่ละอย่างที่ทำดัชนีนั้นเป็นสตริงหรือไม่ตราบใดที่สามารถจัดทำดัชนีได้ดังนั้น:
>>> df['AB'].str.split('-', 1).str[0]
0 A1
1 A2
Name: AB, dtype: object
>>> df['AB'].str.split('-', 1).str[1]
0 B1
1 B2
Name: AB, dtype: object
จากนั้นเป็นเรื่องง่ายที่จะใช้ประโยชน์จาก Python tuple ที่แกะกล่องออกมาเพื่อทำ
>>> df['A'], df['B'] = df['AB'].str.split('-', 1).str
>>> df
AB AB_split A B
0 A1-B1 [A1, B1] A1 B1
1 A2-B2 [A2, B2] A2 B2
แน่นอนว่าการรับ DataFrame ออกจากการแยกคอลัมน์ของสายอักขระนั้นมีประโยชน์มากซึ่ง.str.split()
วิธีการดังกล่าวสามารถทำได้เพื่อคุณโดยใช้expand=True
พารามิเตอร์:
>>> df['AB'].str.split('-', 1, expand=True)
0 1
0 A1 B1
1 A2 B2
ดังนั้นอีกวิธีในการบรรลุสิ่งที่เราต้องการคือการทำ:
>>> df = df[['AB']]
>>> df
AB
0 A1-B1
1 A2-B2
>>> df.join(df['AB'].str.split('-', 1, expand=True).rename(columns={0:'A', 1:'B'}))
AB A B
0 A1-B1 A1 B1
1 A2-B2 A2 B2
expand=True
รุ่นแม้ว่าอีกต่อไปมีข้อได้เปรียบที่แตกต่างกว่าวิธี tuple เอาออก Tuple unpacking ไม่สามารถจัดการกับความยาวที่แตกต่างกันได้ดี:
>>> df = pd.DataFrame({'AB': ['A1-B1', 'A2-B2', 'A3-B3-C3']})
>>> df
AB
0 A1-B1
1 A2-B2
2 A3-B3-C3
>>> df['A'], df['B'], df['C'] = df['AB'].str.split('-')
Traceback (most recent call last):
[...]
ValueError: Length of values does not match length of index
>>>
แต่expand=True
จัดการอย่างดีโดยการวางNone
ในคอลัมน์ที่ "แยก" ไม่เพียงพอ:
>>> df.join(
... df['AB'].str.split('-', expand=True).rename(
... columns={0:'A', 1:'B', 2:'C'}
... )
... )
AB A B C
0 A1-B1 A1 B1 None
1 A2-B2 A2 B2 None
2 A3-B3-C3 A3 B3 C3
read_table()
หรือread_fwf()