Giải pháp được chấp nhận sẽ cực kỳ chậm đối với nhiều dữ liệu. Giải pháp có số lượng upvote lớn nhất là một chút khó đọc và cũng chậm với dữ liệu số. Nếu mỗi cột mới có thể được tính độc lập với các cột khác, tôi sẽ chỉ gán trực tiếp từng cột mà không sử dụng apply
.
Ví dụ với dữ liệu ký tự giả
Tạo 100.000 chuỗi trong DataFrame
df = pd.DataFrame(np.random.choice(['he jumped', 'she ran', 'they hiked'],
size=100000, replace=True),
columns=['words'])
df.head()
words
0 she ran
1 she ran
2 they hiked
3 they hiked
4 they hiked
Giả sử chúng tôi muốn trích xuất một số tính năng văn bản như được thực hiện trong câu hỏi ban đầu. Chẳng hạn, hãy trích xuất ký tự đầu tiên, đếm sự xuất hiện của chữ 'e' và viết hoa cụm từ.
df['first'] = df['words'].str[0]
df['count_e'] = df['words'].str.count('e')
df['cap'] = df['words'].str.capitalize()
df.head()
words first count_e cap
0 she ran s 1 She ran
1 she ran s 1 She ran
2 they hiked t 2 They hiked
3 they hiked t 2 They hiked
4 they hiked t 2 They hiked
Thời gian
%%timeit
df['first'] = df['words'].str[0]
df['count_e'] = df['words'].str.count('e')
df['cap'] = df['words'].str.capitalize()
127 ms ± 585 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
def extract_text_features(x):
return x[0], x.count('e'), x.capitalize()
%timeit df['first'], df['count_e'], df['cap'] = zip(*df['words'].apply(extract_text_features))
101 ms ± 2.96 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
Đáng ngạc nhiên, bạn có thể có hiệu suất tốt hơn bằng cách lặp qua từng giá trị
%%timeit
a,b,c = [], [], []
for s in df['words']:
a.append(s[0]), b.append(s.count('e')), c.append(s.capitalize())
df['first'] = a
df['count_e'] = b
df['cap'] = c
79.1 ms ± 294 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
Một ví dụ khác với dữ liệu số giả
Tạo 1 triệu số ngẫu nhiên và kiểm tra powers
chức năng từ trên.
df = pd.DataFrame(np.random.rand(1000000), columns=['num'])
def powers(x):
return x, x**2, x**3, x**4, x**5, x**6
%%timeit
df['p1'], df['p2'], df['p3'], df['p4'], df['p5'], df['p6'] = \
zip(*df['num'].map(powers))
1.35 s ± 83.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Chỉ định mỗi cột nhanh hơn 25 lần và rất dễ đọc:
%%timeit
df['p1'] = df['num'] ** 1
df['p2'] = df['num'] ** 2
df['p3'] = df['num'] ** 3
df['p4'] = df['num'] ** 4
df['p5'] = df['num'] ** 5
df['p6'] = df['num'] ** 6
51.6 ms ± 1.9 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
Tôi đã thực hiện một phản hồi tương tự với nhiều chi tiết hơn ở đây về lý do tại sao apply
thường không phải là cách để đi.
df.ix[: ,10:16]
. Tôi nghĩ bạn sẽ phảimerge
tính năng của bạn vào bộ dữ liệu.