เมธอด map และ apply ที่พูดถึงใน
บทที่ ๙ นั้นทำให้สามารถจัดการกับข้อมูลภายในตารางพร้อมกันแบบเป็นกลุ่มได้อย่างง่ายดาย
แต่สำหรับข้อมูลที่เป็นสายอักขระแล้วมีคำสั่งอื่นๆอีกจำนวนหนึ่งที่ช่วยให้การจัดการข้อมูลง่ายขึ้นไปอีก จึงอาจจะน่าเรียนรู้เพิ่มเติมเอาไว้สักหน่อย
งานที่เกี่ยวกับสายอักขระจะทำโดยเติม .str ต่อจากชื่อตัวแปรซีรีส์ แล้วตามด้วยชื่อเมธอดต่างๆ
การคัดเอาอักษรบางส่วนจากในแต่ละแถว เติม .str แล้วตามด้วย [] เพื่อเข้าถึงสายอักขระภายในได้เหมือนกับสายอักขระทั่วไป
ตัวอย่าง
import pandas as pd
pokemon = pd.Series([
'ฟุชิงิดาเนะ','ฟุชิงิโซว','ฟุชิงิบานะ',
'ฮิโตคาเงะ','ลิซาร์โด','ลิซาร์ดอน',
'เซนิงาเมะ','คาเมล','คาเม็กซ์'],
index=[1,2,3,4,5,6,7,8,9])
print(pokemon)
ได้
1 ฟุชิงิดาเนะ
2 ฟุชิงิโซว
3 ฟุชิงิบานะ
4 ฮิโตคาเงะ
5 ลิซาร์โด
6 ลิซาร์ดอน
7 เซนิงาเมะ
8 คาเมล
9 คาเม็กซ์
dtype: object
ลองดูอักษรตัวแรกถึงตัวที่ ๖
print(list(pokemon.str[:6]))
# มีค่าเท่ากับ pokemon.apply(lambda x:x[:6])
ได้
['ฟุชิงิ', 'ฟุชิงิ', 'ฟุชิงิ', 'ฮิโตคา', 'ลิซาร์', 'ลิซาร์', 'เซนิงา', 'คาเมล', 'คาเม็ก']
อนึ่ง ผลที่ได้ออกมาจริงๆนั้นเป็นซีรีส์เหมือนเดิม แต่ในที่นี้เพื่อประหยัดพื้นที่ขอแปลงเป็นลิสต์ ตัวอย่างถัดๆไปก็เช่นเดียวกัน
หาความยาวของสายอักขระ สามารถหาความยาวของสายอักขระได้ด้วยเมธอด str.len เช่น
print(list(pokemon.str.len()))
# เท่ากับ pokemon.apply(lambda x:len(x))
ได้
[11, 9, 10, 9, 8, 9, 9, 5, 8]
เติมสายอักขระให้ยาวตามที่ต้องการ เมธอด str.pad มีไว้สำหรับเติมช่องว่างให้สายอักขระเพื่อให้มีความยาวรวมตามต้องการ โดยใส่จำนวนที่ต้องการไปเป็นอาร์กิวเมนต์ตัวแรก และตามด้วยตำแหน่งที่บอกว่าจะเอาตัวหนังสือที่มีอยู่เดิมวางไว้ซ้ายหรือขวาหรือกลาง (left right center)
กรณีที่เลือกตรงกลางอาจใช้เมธอด str.center แทนก็ได้
print(list(pokemon.str.pad(12)))
print(list(pokemon.str.pad(12,'right')))
print(list(pokemon.str.center(12)))
ได้
[' ฟุชิงิดาเนะ', ' ฟุชิงิโซว', ' ฟุชิงิบานะ', ' ฮิโตคาเงะ', ' ลิซาร์โด', ' ลิซาร์ดอน', ' เซนิงาเมะ', ' คาเมล', ' คาเม็กซ์']
['ฟุชิงิดาเนะ ', 'ฟุชิงิโซว ', 'ฟุชิงิบานะ ', 'ฮิโตคาเงะ ', 'ลิซาร์โด ', 'ลิซาร์ดอน ', 'เซนิงาเมะ ', 'คาเมล ', 'คาเม็กซ์ ']
['ฟุชิงิดาเนะ ', ' ฟุชิงิโซว ', ' ฟุชิงิบานะ ', ' ฮิโตคาเงะ ', ' ลิซาร์โด ', ' ลิซาร์ดอน ', ' เซนิงาเมะ ', ' คาเมล ', ' คาเม็กซ์ ']
นำสายอักขระมาต่อกันทั้งหมด สามารถนำสายอักขระจากทุกแถวมาต่อกันได้ด้วยเมธอด str.cat สามารถใส่คีย์เวิร์ด sep เพื่อกำหนดคำที่จะใช้คั่นระหว่างแต่ละตัวที่รวม
print(pokemon.str.cat())
print(pokemon.str.cat(sep='|'))
ได้
ฟุชิงิดาเนะฟุชิงิโซวฟุชิงิบานะฮิโตคาเงะลิซาร์โดลิซาร์ดอนเซนิงาเมะคาเมลคาเม็กซ์
ฟุชิงิดาเนะ|ฟุชิงิโซว|ฟุชิงิบานะ|ฮิโตคาเงะ|ลิซาร์โด|ลิซาร์ดอน|เซนิงาเมะ|คาเมล|คาเม็กซ์
เมธอดที่ใช้กับ regex มีเมธอดมากมายที่ใช้เรกูลาร์เอ็กซ์เพรชชัน (ต่อไปจะเรียกสั้นๆว่า regex)
เรื่องเกี่ยวกับ regex นั้นได้เคยเขียนถึงไว้แล้ว อ่านได้ใน
https://phyblas.hinaboshi.com/20160922 สำหรับการหาว่าสายอักขระมีอักษรหรือข้อความที่ต้องการอยู่หรือไม่อาจใช้เมธอด str.contains
เช่น หาว่ามีคำที่มีสระโออยู่หรือไม่
print(list(pokemon.str.contains('โ[ก-ฮ]')))
# ได้ [False, True, False, True, True, False, False, False, False]
หากต้องการค้นหาว่าขึ้นต้นด้วยตัวที่ต้องการหรือไม่ก็ใช้ str.match
เช่น ลองหาว่าคำไหนขึ้นต้นด้วย ก-ม บ้าง
print(list(pokemon.str.match('[ก-ม]')))
# ได้ [True, True, True, False, False, False, False, True, True]
หากต้องการให้แสดงผลการค้นหาทั้งหมดที่เจอก็ใช้ str.findall
เช่น หาคำที่เป็นสระอาหรือเอะ
print(pokemon.str.findall('เ?[ก-ฮ][าะ]'))
# ได้ [['ดา', 'เนะ'], [], ['บา', 'นะ'], ['คา', 'เงะ'], ['ซา'], ['ซา'], ['งา', 'เมะ'], ['คา'], ['คา']]
หากต้องการนับจำนวนผลการค้นหาที่เจอก็ใช้ str.count
เช่น นับจำนวนพยัญชนะในคำ
print(list(pokemon.str.count('[ก-ฮ]')))
# ได้ [5, 5, 5, 4, 4, 6, 4, 3, 4]
หากต้องการค้นหาเพื่อแทนที่ส่วนที่ค้นเจอก็ใช้ str.replace เช่น
print(list(pokemon.str.replace('า','a')))
# ได้ ['ฟุชิงิดaเนะ', 'ฟุชิงิโซว', 'ฟุชิงิบaนะ', 'ฮิโตคaเงะ', 'ลิซaร์โด', 'ลิซaร์ดอน', 'เซนิงaเมะ', 'คaเมล', 'คaเม็กซ์']
หากต้องการแยกข้อความโดยอาศัยตัวคั่นก็ใช้ str.split
เช่นแยกเมื่อเจอสระอะหรืออา
print(list(pokemon.str.split('[าะ]')))
# ได้ [['ฟุชิงิด', 'เน', ''], ['ฟุชิงิโซว'], ['ฟุชิงิบ', 'น', ''], ['ฮิโตค', 'เง', ''], ['ลิซ', 'ร์โด'], ['ลิซ', 'ร์ดอน'], ['เซนิง', 'เม', ''], ['ค', 'เมล'], ['ค', 'เม็กซ์']]
ผลการแยกปกติแล้วจะอยู่ในรูปลิสต์ แต่ถ้าใส่คีย์เวิร์ด expand=True ก็จะอยู่ในรูปของเดตาเฟรม
print(pokemon.str.split('[ะ-๙]',expand=True))
ได้
|
0 |
1 |
2 |
3 |
4 |
5 |
6 |
1 |
ฟ |
ช |
ง |
ด |
|
น |
|
2 |
ฟ |
ช |
ง |
|
ซว |
None |
None |
3 |
ฟ |
ช |
ง |
บ |
น |
|
None |
4 |
ฮ |
|
ตค |
|
ง |
|
None |
5 |
ล |
ซ |
ร |
|
ด |
None |
None |
6 |
ล |
ซ |
ร |
ดอน |
None |
None |
None |
7 |
|
ซน |
ง |
|
ม |
|
None |
8 |
ค |
|
มล |
None |
None |
None |
None |
9 |
ค |
|
ม |
กซ |
|
None |
None |
ส่วน str.extract จะเป็นการแยกข้อความตามกลุ่มก้อนที่ระบุด้วยวงเล็บ () ใน regex
เช่น
print(pokemon.str.extract('(..)(.{3,4})(.*)',expand=True))
ได้
|
0 |
1 |
2 |
1 |
ฟุ |
ชิงิ |
ดาเนะ |
2 |
ฟุ |
ชิงิ |
โซว |
3 |
ฟุ |
ชิงิ |
บานะ |
4 |
ฮิ |
โตคา |
เงะ |
5 |
ลิ |
ซาร์ |
โด |
6 |
ลิ |
ซาร์ |
ดอน |
7 |
เซ |
นิงา |
เมะ |
8 |
คา |
เมล |
|
9 |
คา |
เม็ก |
ซ์ |
ถ้าต้องการใช้วงเล็บแต่ถ้าต้องการแค่สร้างกลุ่มก้อนเพื่อให้มีผลในการคิดแต่ไม่ต้องการให้นับรวมอยู่ในผลลัพธ์ไปด้วยให้ใส่ ?: ไว้ขึ้นต้นคำในวงเล็บ
ตัวอย่าง
p = '(.*)((?:[ก-ฮ]า(?:ร์)?)|(?:โ[ก-ฮ]))(.+)'
print(pokemon.str.extract(p,expand=True))
ได้
|
0 |
1 |
2 |
1 |
ฟุชิงิ |
ดา |
เนะ |
2 |
ฟุชิงิ |
โซ |
ว |
3 |
ฟุชิงิ |
บา |
นะ |
4 |
ฮิโต |
คา |
เงะ |
5 |
ลิ |
ซาร์ |
โด |
6 |
ลิ |
ซาร์ |
ดอน |
7 |
เซนิ |
งา |
เมะ |
8 |
|
คา |
เมล |
9 |
|
คา |
เม็กซ์ |
เมธอดบางส่วนของสายอักขระ นอกจากที่กล่าวมาข้างต้นแล้ว เมธอดบางส่วนที่ใช้ได้กับข้อมูลชนิดสายอักขระ เช่น lower, upper, strip, lstrip, rstrip, endswith, startswith ก็สามารถใช้ในนี้ได้เช่นกัน
ตัวอย่าง
pokemon = pd.Series([
'FuShIgIdAnE','FuShIgIsOu','FuShIgIbAnA',
'HiToKaGe','LiZaRdO','LiZaRdOn',
'ZeNiGaMe','KaMeIl','KaMeX'],
index=[1,2,3,4,5,6,7,8,9])
print(pd.concat([
pokemon,
pokemon.str.capitalize(),
pokemon.str.lower(),
pokemon.str.upper()],
axis=1))
ได้
|
0 |
1 |
2 |
3 |
1 |
FuShIgIdAnE |
Fushigidane |
fushigidane |
FUSHIGIDANE |
2 |
FuShIgIsOu |
Fushigisou |
fushigisou |
FUSHIGISOU |
3 |
FuShIgIbAnA |
Fushigibana |
fushigibana |
FUSHIGIBANA |
4 |
HiToKaGe |
Hitokage |
hitokage |
HITOKAGE |
5 |
LiZaRdO |
Lizardo |
lizardo |
LIZARDO |
6 |
LiZaRdOn |
Lizardon |
lizardon |
LIZARDON |
7 |
ZeNiGaMe |
Zenigame |
zenigame |
ZENIGAME |
8 |
KaMeIl |
Kameil |
kameil |
KAMEIL |
9 |
KaMeX |
Kamex |
kamex |
KAMEX |
อ้างอิง