ประสิทธิภาพระหว่างคำตอบยอดนิยมมีความแตกต่างกันอย่างมีนัยสำคัญและ Jesse & famaral42 ได้กล่าวถึงเรื่องนี้แล้ว แต่ก็คุ้มค่าที่จะแบ่งปันการเปรียบเทียบที่ยุติธรรมระหว่างคำตอบยอดนิยมและการอธิบายรายละเอียดที่ละเอียดอ่อน แต่สำคัญของคำตอบของเจสซี: การโต้แย้งส่งผ่านไปยัง ฟังก์ชั่นยังมีผลต่อประสิทธิภาพการทำงาน
(Python 3.7.4, นุ่น 1.0.3)
import pandas as pd
import locale
import timeit
def create_new_df_test():
df_test = pd.DataFrame([
{'dir': '/Users/uname1', 'size': 994933},
{'dir': '/Users/uname2', 'size': 109338711},
])
return df_test
def sizes_pass_series_return_series(series):
series['size_kb'] = locale.format_string("%.1f", series['size'] / 1024.0, grouping=True) + ' KB'
series['size_mb'] = locale.format_string("%.1f", series['size'] / 1024.0 ** 2, grouping=True) + ' MB'
series['size_gb'] = locale.format_string("%.1f", series['size'] / 1024.0 ** 3, grouping=True) + ' GB'
return series
def sizes_pass_series_return_tuple(series):
a = locale.format_string("%.1f", series['size'] / 1024.0, grouping=True) + ' KB'
b = locale.format_string("%.1f", series['size'] / 1024.0 ** 2, grouping=True) + ' MB'
c = locale.format_string("%.1f", series['size'] / 1024.0 ** 3, grouping=True) + ' GB'
return a, b, c
def sizes_pass_value_return_tuple(value):
a = locale.format_string("%.1f", value / 1024.0, grouping=True) + ' KB'
b = locale.format_string("%.1f", value / 1024.0 ** 2, grouping=True) + ' MB'
c = locale.format_string("%.1f", value / 1024.0 ** 3, grouping=True) + ' GB'
return a, b, c
นี่คือผลลัพธ์:
9.82 ms ± 377 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
2.34 ms ± 48.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
1.36 ms ± 62.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
752 µs ± 18.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
แจ้งให้ทราบว่า tuples กลับเป็นวิธีที่เร็วที่สุด แต่สิ่งที่ถูกส่งผ่านไปในเป็นอาร์กิวเมนต์ยังมีผลต่อประสิทธิภาพการทำงาน ความแตกต่างในรหัสมีความละเอียดอ่อน แต่การปรับปรุงประสิทธิภาพมีความสำคัญ
การทดสอบ # 4 (การส่งผ่านในค่าเดียว) เร็วกว่าการทดสอบ # 3 ถึงสองเท่า (ผ่านแบบอนุกรม) แม้ว่าการดำเนินการจะเหมือนกันอย่างเห็นได้ชัด
แต่ยังมีอีก ...
3.23 ms ± 141 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
2.31 ms ± 39.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
1.36 ms ± 58.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
694 µs ± 3.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
ในบางกรณี (# 1a และ # 4a) การใช้ฟังก์ชันกับ DataFrame ซึ่งมีคอลัมน์เอาต์พุตอยู่แล้วจะเร็วกว่าการสร้างจากฟังก์ชัน
นี่คือรหัสสำหรับเรียกใช้การทดสอบ:
print('\nAccepted Answer (pass series, return series, new columns dont exist):')
df_test = create_new_df_test()
%timeit result = df_test.apply(sizes_pass_series_return_series, axis=1)
print('Accepted Answer (pass series, return series, new columns exist):')
df_test = create_new_df_test()
df_test = pd.concat([df_test, pd.DataFrame(columns=['size_kb', 'size_mb', 'size_gb'])])
%timeit result = df_test.apply(sizes_pass_series_return_series, axis=1)
print('\nPandafied (pass series, return tuple, new columns dont exist):')
df_test = create_new_df_test()
%timeit df_test[['size_kb', 'size_mb', 'size_gb']] = df_test.apply(sizes_pass_series_return_tuple, axis=1, result_type="expand")
print('Pandafied (pass series, return tuple, new columns exist):')
df_test = create_new_df_test()
df_test = pd.concat([df_test, pd.DataFrame(columns=['size_kb', 'size_mb', 'size_gb'])])
%timeit df_test[['size_kb', 'size_mb', 'size_gb']] = df_test.apply(sizes_pass_series_return_tuple, axis=1, result_type="expand")
print('\nTuples (pass series, return tuple then zip, new columns dont exist):')
df_test = create_new_df_test()
%timeit df_test['size_kb'], df_test['size_mb'], df_test['size_gb'] = zip(*df_test.apply(sizes_pass_series_return_tuple, axis=1))
print('Tuples (pass series, return tuple then zip, new columns exist):')
df_test = create_new_df_test()
df_test = pd.concat([df_test, pd.DataFrame(columns=['size_kb', 'size_mb', 'size_gb'])])
%timeit df_test['size_kb'], df_test['size_mb'], df_test['size_gb'] = zip(*df_test.apply(sizes_pass_series_return_tuple, axis=1))
print('\nTuples (pass value, return tuple then zip, new columns dont exist):')
df_test = create_new_df_test()
%timeit df_test['size_kb'], df_test['size_mb'], df_test['size_gb'] = zip(*df_test['size'].apply(sizes_pass_value_return_tuple))
print('Tuples (pass value, return tuple then zip, new columns exist):')
df_test = create_new_df_test()
df_test = pd.concat([df_test, pd.DataFrame(columns=['size_kb', 'size_mb', 'size_gb'])])
%timeit df_test['size_kb'], df_test['size_mb'], df_test['size_gb'] = zip(*df_test['size'].apply(sizes_pass_value_return_tuple))