Mohamed Elnemr نشر 4 سبتمبر 2021 أرسل تقرير نشر 4 سبتمبر 2021 أود عمل دالة بحيث يتم تطبيقها فقط على عمودين معينين من ال dataframes، حاولت عمل الكود التالي: df['col3'] = df[['col1','col2']].apply(f) لكنه يظهر الخطأ التالي: TypeError: ('<lambda>() takes exactly 2 arguments (1 given)' كيف يمكنني فعل هذا؟ 1 اقتباس
0 Ahmed Sharshar نشر 4 سبتمبر 2021 أرسل تقرير نشر 4 سبتمبر 2021 يمكنك استخدام الدالة apply لتطبيق أي دالة تريدها على الأعمدة التي تريد حيث نقوم بوضع axis=1 لاختيار الأعمدة بينما نضع axis=0 اذا اردنا اختيار صفوف بعينها، أنظر المثال التالي: In [1]: df Out[1]: 0 1 0 1.000000 0.000000 1 -0.494375 0.570994 2 1.000000 0.000000 3 1.876360 -0.229738 4 1.000000 0.000000 In [2]: def f(x): return x[0] + x[1] In [3]: df.apply(f, axis=1) Out[3]: 0 1.000000 1 0.076619 2 1.000000 3 1.646622 4 1.000000 أو يمكنك استخدام الكود التالي بتحديد أسماء الأعمدة التى تريدها: df['col3'] = df.apply(lambda x: f(x.col1, x.col2), axis=1) الكود التالي يوضح كيف تستخدم هذة الطريقة بعد تعريف دالة معينة: import pandas as pd df = pd.DataFrame({'ID':['1', '2', '3'], 'col1': [0, 1, 2], 'col2':[3, 4, 5]}) mylist = ['a', 'b', 'c', 'd', 'e', 'f'] def get_sublist(sta,end): return mylist[sta:end+1] df['col3'] = df.apply(lambda x: get_sublist(x.col1, x.col2), axis=1) ويكون الناتج كالتالي: ID col1 col2 col_3 0 1 0 3 [a, b, c, d] 1 2 1 4 [b, c, d, e] 2 3 2 5 [c, d, e, f] ويمكنك تحديد اسماء الأعمدة التي تريد لتطبيق الدالة عليهم مهما كان عددهم. اقتباس
0 Ali Haidar Ahmad نشر 4 سبتمبر 2021 أرسل تقرير نشر 4 سبتمبر 2021 (معدل) كما أشار أحمد يمكنك استخدام Apply لكن أنصح دوماً بالاعتماد على طرق أخرى لأن هذه الطرق بطيئة، لذا يمكن أن نقوم بالأمر من خلال الدالة vectorize التي ستعطيك فرق كبير للغاية بالسرعة كالتالي: import pandas as pd # تعرف داتا فريم لنختبر عليه df = pd.DataFrame({'ID':['1', '2', '3'], 'col1': [0, 1, 2], 'col2':[3, 4, 5]}) df """ ID col1 col2 0 1 0 3 1 2 1 4 2 3 2 5 """ # نعرف تابع لنختبر عليه def f(x,y): return x+y import numpy as np # نقوم بتطبيق التابع على عمودي البيانات df.loc[:,'result'] = np.vectorize(f) (df['col1'], df['col2']) df """ ID col1 col2 result 0 1 0 3 3 1 2 1 4 5 2 3 2 5 7 """ كذلك كان بإمكانك استخدام الدالة apply: df['col_3'] = df.apply(lambda x: f(x.col1, x.col2), axis=1) df """ ID col1 col2 col_3 0 1 0 3 3 1 2 1 4 5 2 3 2 5 7 """ وكتحسين لسرعة التنفيذ باستخدام apply يمكنك استخدام الأداة swifter: import swifter df['col_3'] = df.swifter.apply(lambda x: f(x.col1, x.col2), axis=1) للمقارنة: # توليد داتافريم بحجم كبير df1 = df.sample(100000, replace=True).reset_index(drop=True) # تطبيق نفس العملية واستخلاص زمن التنفيذ %timeit df1.apply(lambda x: f(x.col1, x.col2), axis=1) # 1 loop, best of 5: 1.84 s per loop %timeit df1.swifter.apply(lambda x: f(x.col1, x.col2), axis=1) # 100 loops, best of 5: 2.24 ms per loop %timeit np.vectorize(f) (df['col1'], df['col2']) # 10000 loops, best of 5: 62.7 µs per loop لاحظ أن apply استغرقت ثانيتين تقريباً وع التحسين swifter استغرقت 2 ونصف ميلي ثانية، لكن باستخدام vectorize استغرقت 62 ميكرو ثانية وهو فرق هائل. وهنا نتحدث عن عمليات بسيطة جداً هناك عمليات قد يتطلب تنفيذها وقت يتجاوز النصف ساعة والساعة حتى تنتهي لو استخدمنا Apply. لذا إذا كنت تفكر بالتعامل مع بيانات ضخمة ابتعد عنها. تم التعديل في 4 سبتمبر 2021 بواسطة Ali Haidar Ahmad 1 اقتباس
0 عبدالباسط ابراهيم نشر 5 سبتمبر 2021 أرسل تقرير نشر 5 سبتمبر 2021 يمكنك أيضاً استخدام ال loop لتنفيذ المطلوب وهذه الطريقة هي أسرع من استخدام apply مع axis 1 كما في المثال التالي import pandas as pd df = pd.DataFrame({'ID':['1','2','3'], 'col_1': [0,2,3], 'col_2':[1,4,5]}) mylist = ['a','b','c','d','e','f'] def get_sublist(sta,end): return mylist[sta:end+1] df['col_3'] = list(map(get_sublist,df['col_1'],df['col_2'])) ملاحظة في الإصدار Python 2 لا تحتاج لاستخدام ال list للتحويل اقتباس
السؤال
Mohamed Elnemr
أود عمل دالة بحيث يتم تطبيقها فقط على عمودين معينين من ال dataframes، حاولت عمل الكود التالي:
لكنه يظهر الخطأ التالي:
كيف يمكنني فعل هذا؟
3 أجوبة على هذا السؤال
Recommended Posts
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.