এর থেকে তালিকা ফিরিয়ে apply
নেওয়া একটি বিপজ্জনক অপারেশন, কারণ ফলস্বরূপ অবজেক্টটি সিরিজ বা ডেটাফ্রেম হিসাবে গ্যারান্টিযুক্ত নয়। এবং ব্যতিক্রম কিছু ক্ষেত্রে উত্থাপিত হতে পারে। আসুন একটি সহজ উদাহরণ দিয়ে চলুন:
df = pd.DataFrame(data=np.random.randint(0, 5, (5,3)),
columns=['a', 'b', 'c'])
df
a b c
0 4 0 0
1 2 0 1
2 2 2 2
3 1 2 2
4 3 0 0
এখান থেকে একটি তালিকা ফেরত নিয়ে তিনটি সম্ভাব্য ফলাফল রয়েছে apply
1) যদি প্রত্যাবর্তিত তালিকার দৈর্ঘ্য কলামের সংখ্যার সমান না হয়, তবে তালিকাগুলির একটি সিরিজ ফিরে আসে returned
df.apply(lambda x: list(range(2)), axis=1) # returns a Series
0 [0, 1]
1 [0, 1]
2 [0, 1]
3 [0, 1]
4 [0, 1]
dtype: object
২) প্রত্যাবর্তিত তালিকার দৈর্ঘ্য কলামের সংখ্যার সমান হলে একটি ডাটাফ্রেম ফিরে আসে এবং প্রতিটি কলাম তালিকায় সংশ্লিষ্ট মান পায় gets
df.apply(lambda x: list(range(3)), axis=1) # returns a DataFrame
a b c
0 0 1 2
1 0 1 2
2 0 1 2
3 0 1 2
4 0 1 2
3) যদি প্রত্যাবর্তিত তালিকার দৈর্ঘ্য প্রথম সারির কলামগুলির সংখ্যার সমান হয় তবে কমপক্ষে একটি সারি থাকে যেখানে তালিকার একটি কলামের সংখ্যার তুলনায় উপাদানগুলির একটি পৃথক সংখ্যা রয়েছে যেখানে একটি ভ্যালু এরির উত্থাপিত হয়।
i = 0
def f(x):
global i
if i == 0:
i += 1
return list(range(3))
return list(range(4))
df.apply(f, axis=1)
ValueError: Shape of passed values is (5, 4), indices imply (5, 3)
আবেদন না করেই সমস্যার উত্তর দেওয়া
apply
অক্ষ = 1 দিয়ে ব্যবহার করা খুব ধীর। বেসিক পুনরাবৃত্ত পদ্ধতিগুলির সাথে আরও ভাল পারফরম্যান্স পাওয়া সম্ভব (বিশেষত বৃহত্তর ডেটাসেটে)।
বৃহত্তর ডেটাফ্রেম তৈরি করুন
df1 = df.sample(100000, replace=True).reset_index(drop=True)
সময়
# apply is slow with axis=1
%timeit df1.apply(lambda x: mylist[x['col_1']: x['col_2']+1], axis=1)
2.59 s ± 76.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
# zip - similar to @Thomas
%timeit [mylist[v1:v2+1] for v1, v2 in zip(df1.col_1, df1.col_2)]
29.5 ms ± 534 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
@ থমাস উত্তর
%timeit list(map(get_sublist, df1['col_1'],df1['col_2']))
34 ms ± 459 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)