The str
accessor yang tersedia untuk pandas.Series
objek dtype == object
sebenarnya merupakan iterable.
Asumsikan pandas.DataFrame
df
:
df = pd.DataFrame(dict(col=[*zip('abcdefghij', range(10, 101, 10))]))
df
col
0 (a, 10)
1 (b, 20)
2 (c, 30)
3 (d, 40)
4 (e, 50)
5 (f, 60)
6 (g, 70)
7 (h, 80)
8 (i, 90)
9 (j, 100)
Kami dapat menguji apakah itu dapat diulang
from collections import Iterable
isinstance(df.col.str, Iterable)
True
Kami kemudian dapat menetapkan darinya seperti kami melakukan iterable lainnya:
var0, var1 = 'xy'
print(var0, var1)
x y
Solusi paling sederhana
Jadi dalam satu baris kita dapat menetapkan kedua kolom tersebut
df['a'], df['b'] = df.col.str
df
col a b
0 (a, 10) a 10
1 (b, 20) b 20
2 (c, 30) c 30
3 (d, 40) d 40
4 (e, 50) e 50
5 (f, 60) f 60
6 (g, 70) g 70
7 (h, 80) h 80
8 (i, 90) i 90
9 (j, 100) j 100
Solusi lebih cepat
Hanya sedikit lebih rumit, kita dapat menggunakan zip
untuk membuat iterable serupa
df['c'], df['d'] = zip(*df.col)
df
col a b c d
0 (a, 10) a 10 a 10
1 (b, 20) b 20 b 20
2 (c, 30) c 30 c 30
3 (d, 40) d 40 d 40
4 (e, 50) e 50 e 50
5 (f, 60) f 60 f 60
6 (g, 70) g 70 g 70
7 (h, 80) h 80 h 80
8 (i, 90) i 90 i 90
9 (j, 100) j 100 j 100
Di barisan
Artinya, jangan mutasi yang sudah ada df
Ini berfungsi karena assign
mengambil argumen kata kunci di mana kata kuncinya adalah nama kolom baru (atau yang sudah ada) dan nilainya akan menjadi nilai kolom baru. Anda dapat menggunakan kamus dan mengekstraknya **
serta bertindak sebagai argumen kata kunci. Jadi ini adalah cara cerdas untuk menetapkan kolom baru bernama 'g'
item pertama di df.col.str
iterable dan 'h'
itu adalah item kedua di df.col.str
iterable.
df.assign(**dict(zip('gh', df.col.str)))
col g h
0 (a, 10) a 10
1 (b, 20) b 20
2 (c, 30) c 30
3 (d, 40) d 40
4 (e, 50) e 50
5 (f, 60) f 60
6 (g, 70) g 70
7 (h, 80) h 80
8 (i, 90) i 90
9 (j, 100) j 100
list
Pendekatan versi saya
Dengan pemahaman daftar modern dan pembongkaran variabel.
Catatan: juga menggunakan inlinejoin
df.join(pd.DataFrame([*df.col], df.index, [*'ef']))
col g h
0 (a, 10) a 10
1 (b, 20) b 20
2 (c, 30) c 30
3 (d, 40) d 40
4 (e, 50) e 50
5 (f, 60) f 60
6 (g, 70) g 70
7 (h, 80) h 80
8 (i, 90) i 90
9 (j, 100) j 100
Versi mutasi akan menjadi
df[['e', 'f']] = pd.DataFrame([*df.col], df.index)
Tes Waktu yang Naif
DataFrame pendek
Gunakan salah satu yang ditentukan di atas
%timeit df.assign(**dict(zip('gh', df.col.str)))
%timeit df.assign(**dict(zip('gh', zip(*df.col))))
%timeit df.join(pd.DataFrame([*df.col], df.index, [*'gh']))
1.16 ms ± 21.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
635 µs ± 18.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
795 µs ± 42.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
DataFrame Panjang
10 ^ 3 kali lebih besar
df = pd.concat([df] * 1000, ignore_index=True)
%timeit df.assign(**dict(zip('gh', df.col.str)))
%timeit df.assign(**dict(zip('gh', zip(*df.col))))
%timeit df.join(pd.DataFrame([*df.col], df.index, [*'gh']))
11.4 ms ± 1.53 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)
2.1 ms ± 41.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
2.33 ms ± 35.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)