TL; versi DR:
Untuk kasus sederhana:
- Saya memiliki kolom teks dengan pembatas dan saya ingin dua kolom
Solusi paling sederhana adalah:
df['A'], df['B'] = df['AB'].str.split(' ', 1).str
Atau Anda dapat membuat membuat DataFrame dengan satu kolom untuk setiap entri pemisahan secara otomatis dengan:
df['AB'].str.split(' ', 1, expand=True)
Anda harus menggunakan expand=True
jika string Anda memiliki jumlah split yang tidak seragam dan Anda ingin None
mengganti nilai yang hilang.
Perhatikan bagaimana, dalam kedua kasus itu, .tolist()
metode ini tidak perlu. Tidak juga zip()
.
Secara terperinci:
Solusi Andy Hayden paling baik dalam menunjukkan kekuatan str.extract()
metode ini.
Tetapi untuk pemisahan sederhana di atas pemisah yang diketahui (seperti, membelah dengan garis, atau membelah dengan spasi), .str.split()
metode ini cukup 1 . Ini beroperasi pada kolom (Seri) string, dan mengembalikan kolom (Seri) daftar:
>>> 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: Jika Anda tidak yakin apa yang dilakukan dua parameter pertama .str.split()
, saya merekomendasikan dokumen untuk versi metode Python sederhana .
Tapi bagaimana cara Anda:
- kolom yang berisi daftar dua elemen
untuk:
- dua kolom, masing-masing berisi elemen daftar masing-masing?
Nah, kita perlu melihat lebih dekat .str
atribut kolom.
Ini adalah objek ajaib yang digunakan untuk mengumpulkan metode yang memperlakukan setiap elemen dalam kolom sebagai string, dan kemudian menerapkan metode masing-masing di setiap elemen seefisien mungkin:
>>> 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
Tetapi ia juga memiliki antarmuka "pengindeksan" untuk mendapatkan setiap elemen string dengan indeksnya:
>>> df['AB'].str[0]
0 A
1 A
Name: AB, dtype: object
>>> df['AB'].str[1]
0 1
1 2
Name: AB, dtype: object
Tentu saja, antarmuka pengindeksan .str
ini tidak terlalu peduli jika setiap elemen yang diindeksinya sebenarnya adalah string, asalkan dapat diindeks, jadi:
>>> 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
Kemudian, ini adalah masalah sederhana mengambil keuntungan dari tuple Python membongkar iterables untuk dilakukan
>>> 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
Tentu saja, mengeluarkan DataFrame dari pemisahan kolom string sangat berguna sehingga .str.split()
metode ini dapat melakukannya untuk Anda dengan expand=True
parameter:
>>> df['AB'].str.split('-', 1, expand=True)
0 1
0 A1 B1
1 A2 B2
Jadi, cara lain untuk mencapai apa yang kita inginkan adalah dengan melakukan:
>>> 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
The expand=True
versi, meskipun lagi, memiliki keuntungan yang berbeda atas metode tupel membongkar. Tuple unpacking tidak cocok dengan pemisahan dengan panjang yang berbeda:
>>> 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
>>>
Tetapi expand=True
atasi dengan baik dengan menempatkan None
di kolom yang tidak memiliki "pemisahan" yang cukup:
>>> 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()
atauread_fwf()