পান্ডাস ডাটাফ্রেমের দুটি কলামে কীভাবে কোনও ফাংশন প্রয়োগ করতে হবে


368

ধরুন আমার কাছে একটি রয়েছে dfযার কলাম রয়েছে 'ID', 'col_1', 'col_2'। এবং আমি একটি ফাংশন সংজ্ঞায়িত:

f = lambda x, y : my_function_expression

এখন আমি প্রয়োগ করতে চান fকরতে dfএর দুটি কলাম 'col_1', 'col_2'উপাদান-অনুযায়ী গণনা করা হবে একটি নতুন কলাম 'col_3'কিছুটা মত:

df['col_3'] = df[['col_1','col_2']].apply(f)  
# Pandas gives : TypeError: ('<lambda>() takes exactly 2 arguments (1 given)'

কিভাবে করবেন ?

** নীচে হিসাবে বিশদ নমুনা যুক্ত করুন ***

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'] = df[['col_1','col_2']].apply(get_sublist,axis=1)
# expect above to output df as below 

  ID  col_1  col_2            col_3
0  1      0      1       ['a', 'b']
1  2      2      4  ['c', 'd', 'e']
2  3      3      5  ['d', 'e', 'f']

4
আপনি কি সরাসরি কলামগুলিতে এফ প্রয়োগ করতে পারেন: ডিএফ ['কল_3'] = এফ (ডিএফ ['কোল_1'], ডিএফ ['কল_2'])
বেটেল

1
কি দরকারী হবে fকরছে
tehmisvh

2
না, ডিএফ ['কল_3'] = এফ (ডিএফ ['কোল_1'], ডিএফ ['কল_2']) কাজ করছে না। এফের জন্য কেবল স্কেলার ইনপুট গ্রহণ করে, ভেক্টর ইনপুটগুলি নয়। ঠিক আছে, আপনি f = ল্যাম্বদা এক্স, y: x + y ধরে নিতে পারেন। (অবশ্যই, আমার আসল চটি এতটা সহজ নয়, অন্যথায় আমি সরাসরি ডিএফ করতে পারি ['col_3'] = ডিএফ ['কল_1'] + ডিএফ ['কোল_2'])
বড়বাগ

1
আমি নীচে url এ সম্পর্কিত প্রশ্নোত্তর পেয়েছি, তবে আমার ইস্যুটি 1 থেকে 2 নয়, দুটি বিদ্যমান কলাম দ্বারা একটি নতুন কলাম গণনা করছে। stackoverflow.com/questions/12356501/...
bigbug

আমি আমার প্রতিক্রিয়া মনে stackoverflow.com/a/52854800/5447172 কোন সমাধান নীচে উপস্থিত বা সাংখ্যিক ইন্ডেক্স সঙ্গে সবচেয়ে Pythonic / Pandanic ভাবে এই উত্তর। এটি আপনার উদাহরণে আপনাকে প্রয়োজনীয় আউটপুট তৈরি করে।
আজরহাইট

উত্তর:


291

এখানে applyডেটাফ্রেম ব্যবহার করে একটি উদাহরণ দেওয়া হচ্ছে, যা আমি কল করছি axis = 1

পার্থক্যটি লক্ষ্য করুন যে ফাংশনটিতে দুটি মান পাস করার চেষ্টা করার পরিবর্তে fএকটি পান্ডাস সিরিজ অবজেক্ট গ্রহণ করার জন্য ফাংশনটি পুনরায় লিখুন এবং তারপরে সিরিজটিকে প্রয়োজনীয় মানগুলি পেতে সূচী করুন।

In [49]: df
Out[49]: 
          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 [50]: def f(x):    
   ....:  return x[0] + x[1]  
   ....:  

In [51]: df.apply(f, axis=1) #passes a Series object, row-wise
Out[51]: 
0    1.000000
1    0.076619
2    1.000000
3    1.646622
4    1.000000

আপনার ব্যবহারের ক্ষেত্রে উপর নির্ভর করে এটি কখনও কখনও পান্ডাস তৈরি করতে সহায়ক group অবজেক্ট করতে সহায়তা applyকরে এবং তারপরে গ্রুপে ব্যবহার করে।


হ্যাঁ, আমি প্রয়োগটি ব্যবহার করার চেষ্টা করেছি, তবে বৈধ সিনট্যাক্স এক্সপ্রেশনটি খুঁজে পাই না। এবং যদি ডিএফের প্রতিটি সারিটি স্বতন্ত্র হয় তবে এখনও গ্রুপবাই ব্যবহার করবেন?
বড়বাগ

আমার উত্তরে একটি উদাহরণ যুক্ত হয়েছে, আশা করি এটি আপনি যা খুঁজছেন তা করে। যদি তা না হয় তবে দয়া করে একটি আরও নির্দিষ্ট উদাহরণ ফাংশন সরবরাহ করুন যেহেতু sumএখন পর্যন্ত প্রস্তাবিত কোনও পদ্ধতি দ্বারা সফলভাবে সমাধান করা হয়েছে is
আমান

1
আপনি কি আপনার কোডটি পেস্ট করবেন? আমি ফাংশনটি আবার লিখি: Def get_sublist (x): mylist [x [1]: x [2] + 1] এবং df ['col_3'] = df.apply (get_sublist, axis = 1) দেয় 'ValueError: অপারেশনগুলি পারে আকার (2) (3) '
বিগব্যাগ

3
@ আমান: পান্ডাস সংস্করণ ০.০৪.১ সহ (এবং সম্ভবত পূর্ববর্তী), ব্যবহার ল্যাম্বডা এক্সপ্রেশনটিও ব্যবহার করতে পারে। dfআপনার সংজ্ঞায়িত অবজেক্টটি দিন , অন্য পদ্ধতির (সমমানের ফলাফল সহ) হ'ল df.apply(lambda x: x[0] + x[1], axis = 1)
জুবলস

2
@CanCeylan আপনি শুধু তারপর ইনডেক্স পরিবর্তে ফাংশন কলাম নাম ব্যবহার করতে পারেন পরিবর্তন আদেশ সম্পর্কে চিন্তা করতে হবে না, বা নাম দ্বারা সূচক পেতে যেমন দেখতে stackoverflow.com/questions/13021654/...
দাভোসে

165

পান্ডসে এটি করার একটি পরিষ্কার, এক-লাইন উপায় রয়েছে:

df['col_3'] = df.apply(lambda x: f(x.col_1, x.col_2), axis=1)

এটি fএকাধিক ইনপুট মানগুলির সাথে একটি ব্যবহারকারী-সংজ্ঞায়িত ফাংশন হতে পারে এবং কলামগুলিতে অ্যাক্সেসের জন্য (অনিরাপদ) সংখ্যাসূচক সূচকগুলির পরিবর্তে (নিরাপদ) কলামের নাম ব্যবহার করে।

ডেটা সহ উদাহরণ (মূল প্রশ্নের উপর ভিত্তি করে):

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'] = df.apply(lambda x: get_sublist(x.col_1, x.col_2), axis=1)

এর আউটপুট print(df):

  ID  col_1  col_2      col_3
0  1      0      1     [a, b]
1  2      2      4  [c, d, e]
2  3      3      5  [d, e, f]

যদি আপনার কলামের নামগুলিতে স্পেস থাকে বা বিদ্যমান ডাটাফ্রেম বৈশিষ্ট্যের সাথে একটি নাম ভাগ করে নেওয়া যায় তবে আপনি বর্গাকার বন্ধনীগুলির সাথে সূচক করতে পারেন:

df['col_3'] = df.apply(lambda x: f(x['col 1'], x['col 2']), axis=1)

2
দ্রষ্টব্য, যদি ব্যবহার করা হয় axis=1এবং আপনার কলামটি বলা হয় তবে nameএটি আসলে আপনার কলামের ডেটা ফেরত দেবে না indexnameএকটি পেতে হিসাবে অনুরূপ groupby()। আমি আমার কলামটির নাম পরিবর্তন করে এটি সমাধান করেছি।
টম হেমস

2
এই হল! আমি ঠিক বুঝতে পারি নি যে আপনি ল্যাম্বডাসে একাধিক ইনপুট পরামিতি সহ ব্যবহারকারী-সংজ্ঞায়িত ফাংশন inোকাতে পারবেন। এটি মনে রাখা গুরুত্বপূর্ণ (আমি মনে করি) আপনি সিরিজ.প্লাই () এর পরিবর্তে ডিএফ.প্ল্লি () ব্যবহার করছেন। এটি আপনাকে চাইলে দুটি কলাম ব্যবহার করে ডিএফকে সূচী করতে দেয় এবং পুরো কলামটি ফাংশনে সরিয়ে দেয়, তবে আপনি প্রয়োগ () ব্যবহার করছেন বলে এটি পুরো কলামে উপাদান-ভিত্তিক ফ্যাশনে ফাংশনটি প্রয়োগ করে। উজ্জ্বল! পোস্ট করার জন্য আপনাকে ধন্যবাদ!
ডেটা-ফাইলে 31'19

1
অবশেষে! তুমি আমার দিন বাঁচিয়েছ!
মিস্টেরিও

আমি বিশ্বাস করি এটি করার প্রস্তাবিত উপায় হল df.loc [:, 'new col'] = df.apply .....
ভ্যালারনার

@ ভ্যালারনার আমি .locউদাহরণটিতে পছন্দ করার কোনও কারণ মনে করি না । এটির প্রয়োজন হতে পারে যদি আপনি এটি অন্য কোনও সমস্যা সেটিংসের সাথে খাপ খাইয়ে নেন (যেমন টুকরোগুলির সাহায্যে কাজ করা)।
আজরবাইট

86

একটি সহজ সমাধান হ'ল:

df['col_3'] = df[['col_1','col_2']].apply(lambda x: f(*x), axis=1)

1
এই উত্তরটি কীভাবে জিজ্ঞাসাবাদে পৃথক হয়েছে: df ['col_3'] = df [['কোল_1', 'কল_2']]। প্রয়োগ করতে (চ) ঠিক নিশ্চিত করতে, প্রশ্নে পদ্ধতির কাজ হয়নি কারণ পোস্টারটি এই অক্ষটি = 1 নির্দিষ্ট করে নি, ডিফল্টটি অক্ষ = 0?
হারিয়ে গেছে 1

1
এই উত্তরটি @ আনমানের উত্তরের সাথে তুলনীয় তবে কিছুটা চটচটে। তিনি একটি বেনামি ফাংশন তৈরি করছেন যা একটি পুনরাবৃত্তযোগ্য লাগে এবং এটি এফ ফাংশনে পাস করার আগে এটি প্যাক করে দেয়।
টিয়াও

39

একটি মজার প্রশ্ন! আমার উত্তর নীচে হিসাবে:

import pandas as pd

def sublst(row):
    return lst[row['J1']:row['J2']]

df = pd.DataFrame({'ID':['1','2','3'], 'J1': [0,2,3], 'J2':[1,4,5]})
print df
lst = ['a','b','c','d','e','f']

df['J3'] = df.apply(sublst,axis=1)
print df

আউটপুট:

  ID  J1  J2
0  1   0   1
1  2   2   4
2  3   3   5
  ID  J1  J2      J3
0  1   0   1     [a]
1  2   2   4  [c, d]
2  3   3   5  [d, e]

আইডি <জে 1 <জে 2 <জ 3 এ আইডি নিশ্চিত করতে আমি কলামের নামটি আইডি, জে 1, জে 2, জ 3 এ পরিবর্তিত করেছি, তাই ডান অনুক্রমে কলামটি প্রদর্শন করা হবে।

আরও একটি সংক্ষিপ্ত সংস্করণ:

import pandas as pd

df = pd.DataFrame({'ID':['1','2','3'], 'J1': [0,2,3], 'J2':[1,4,5]})
print df
lst = ['a','b','c','d','e','f']

df['J3'] = df.apply(lambda row:lst[row['J1']:row['J2']],axis=1)
print df

23

আপনি যে পদ্ধতিটি সন্ধান করছেন তা হ'ল সিরিজ ডটকম ine তবে, এটি দেখে মনে হচ্ছে ডেটাটাইপগুলির আশেপাশে কিছু যত্ন নেওয়া উচিত। আপনার উদাহরণে, আপনি (উত্তরটি পরীক্ষার সময় যেমনটি করেছিলেন) নির্লজ্জভাবে কল করবেন

df['col_3'] = df.col_1.combine(df.col_2, func=get_sublist)

তবে এটি ত্রুটি ছুঁড়ে ফেলেছে:

ValueError: setting an array element with a sequence.

আমার সেরা অনুমানটি মনে হয় যে ফলটি পদ্ধতিটি (df.col_1 এখানে কল করা) সিরিজের মতো একই ধরণের হবে বলে মনে হয়। তবে, নিম্নলিখিত কাজ করে:

df['col_3'] = df.col_1.astype(object).combine(df.col_2, func=get_sublist)

df

   ID   col_1   col_2   col_3
0   1   0   1   [a, b]
1   2   2   4   [c, d, e]
2   3   3   5   [d, e, f]

12

আপনি যেভাবে চ লিখেছেন তাতে দুটি ইনপুট দরকার। আপনি যদি ত্রুটির বার্তাটি দেখেন তবে এটি বলবে যে আপনি চ কে মাত্র দুটি ইনপুট সরবরাহ করছেন না। ত্রুটির বার্তাটি সঠিক।
মেলে না কারণ df [['col1', 'col2']] দুটি পৃথক কলাম নয়, দুটি কলাম সহ একটি একক ডাটাফ্রেম প্রদান করে।

আপনাকে আপনার এফ পরিবর্তন করতে হবে যাতে এটি একটি একক ইনপুট নেয়, উপরের ডেটা ফ্রেমটিকে ইনপুট হিসাবে রাখুন, তারপরে এটি ফাংশনের বডিটির ভিতরে এক্স, ওয়াই করে ফেলুন । তারপরে আপনার যা যা প্রয়োজন তা করুন এবং একটি মান প্রদান করুন।

আপনার এই ফাংশনটির স্বাক্ষর প্রয়োজন কারণ বাক্য গঠনটি অ্যাপ্লিকেশন (চ) তাই চ একক জিনিস = ডেটাফ্রেম নেওয়া দরকার এবং দুটি জিনিস নয় যা আপনার বর্তমান চটি প্রত্যাশা করে।

যেহেতু আপনি চ এর বডি সরবরাহ করেননি আমি আরও বিশদে সাহায্য করতে পারি না - তবে এটি আপনার কোডটি মৌলিকভাবে পরিবর্তন না করে বা প্রয়োগের পরিবর্তে কিছু অন্যান্য পদ্ধতি ব্যবহার না করেই বাইরে যাওয়ার উপায় সরবরাহ করতে পারে


12

আমি np.vectorize জন্য একটি ভোট দিতে যাচ্ছি। এটি আপনাকে কেবলমাত্র x সংখ্যক কলামগুলিতে শ্যুট করতে এবং ফাংশনে ডেটাফ্রেমের সাথে ডিল করার অনুমতি দেয়, সুতরাং যে ফাংশনগুলিতে আপনি 2 কলাম এবং একটি ধ্রুবক পাঠানোর মতো নিয়ন্ত্রণ করেন না বা করছেন এমন কোনও কাজগুলির জন্য এটি দুর্দান্ত (যেমন কল_1, কল_2, 'foo বিন্যাস')।

import numpy as np
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'] = df[['col_1','col_2']].apply(get_sublist,axis=1)
# expect above to output df as below 

df.loc[:,'col_3'] = np.vectorize(get_sublist, otypes=["O"]) (df['col_1'], df['col_2'])


df

ID  col_1   col_2   col_3
0   1   0   1   [a, b]
1   2   2   4   [c, d, e]
2   3   3   5   [d, e, f]

1
এটি সত্যই পান্ডাস ব্যবহার করে প্রশ্নের উত্তর দেয় না।
mnky9800n

18
প্রশ্নটি "পান্ডস ডেটাফ্রেমের দুটি কলামে একটি ফাংশন কীভাবে প্রয়োগ করতে হবে" তা নয় "কীভাবে কেবল পান্ডাস পদ্ধতি ব্যবহার করে পান্ডস ডেটাফ্রেমের দুটি কলামে কোনও ফাংশন প্রয়োগ করতে হবে" এবং নম্পিটি পান্ডসের নির্ভরতা তাই আপনাকে এটি যেভাবেই ইনস্টল করতে হবে, সুতরাং এটি একটি অদ্ভুত আপত্তি মত মনে হচ্ছে।
ট্রে ওয়ালেস

12

এর থেকে তালিকা ফিরিয়ে 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)

1
এটি শেখা সম্ভব যেখানে থেকে এত বিস্তারিত উত্তর দেখে ভাল লাগল answers
Andrea Moro

7

আমি নিশ্চিত যে এটি পান্ডাস বা নম্পি অপারেশনগুলি ব্যবহার করে সমাধানগুলির মতো তত দ্রুত নয়, তবে আপনি যদি নিজের ফাংশনটি আবার লিখতে না চান তবে আপনি মানচিত্রটি ব্যবহার করতে পারেন। মূল উদাহরণ ডেটা ব্যবহার করে -

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']))
#In Python 2 don't convert above to list

আমরা ফাংশনটিতে এভাবে যেতে চেয়ে যতগুলি আর্গুমেন্ট পাস করতে পারি। আউটপুট আমরা কি চেয়েছিলেন

ID  col_1  col_2      col_3
0  1      0      1     [a, b]
1  2      2      4  [c, d, e]
2  3      3      5  [d, e, f]


2

আপনার প্রশ্নের আমার উদাহরণ:

def get_sublist(row, col1, col2):
    return mylist[row[col1]:row[col2]+1]
df.apply(get_sublist, axis=1, col1='col_1', col2='col_2')

2

আপনার যদি বিশাল ডেটা সেট থাকে তবে আপনি সুইফটারটি ব্যবহার করে এটি করার সহজ তবে দ্রুত (কার্যকর সময়) ব্যবহার করতে পারেন:

import pandas as pd
import swifter

def fnc(m,x,c):
    return m*x+c

df = pd.DataFrame({"m": [1,2,3,4,5,6], "c": [1,1,1,1,1,1], "x":[5,3,6,2,6,1]})
df["y"] = df.swifter.apply(lambda x: fnc(x.m, x.x, x.c), axis=1)

1

আমি মনে করি আপনি get_sublistফাংশন পরিবর্তন করতে চান না , এবং কাজটি করার জন্য কেবল ডেটাফ্রেমের applyপদ্ধতিটি ব্যবহার করতে চান । আপনি যে ফলাফলটি চান তা পেতে, আমি দুটি সহায়তা ফাংশন লিখেছি: get_sublist_listএবং unlist। ফাংশনটির নাম হিসাবে, প্রথমে সাবলিস্টের তালিকাটি পান, দ্বিতীয়টি সেই তালিকা থেকে সেই সাবলিস্টটি বের করুন। শেষ পর্যন্ত, applyএই দুটি ফাংশন df[['col_1','col_2']]পরবর্তীকালে ডেটাফ্রেমে প্রয়োগ করার জন্য আমাদের ফাংশনটি কল করতে হবে ।

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]

def get_sublist_list(cols):
    return [get_sublist(cols[0],cols[1])]

def unlist(list_of_lists):
    return list_of_lists[0]

df['col_3'] = df[['col_1','col_2']].apply(get_sublist_list,axis=1).apply(unlist)

df

আপনি যদি ফাংশনটি []বন্ধ করতে ব্যবহার না করেন get_sublist, তবে get_sublist_listফাংশনটি একটি সরল তালিকা ফিরিয়ে দেবে, এটি উত্থাপন করবে ValueError: could not broadcast input array from shape (3) into shape (2), যেমন @ টেড পেট্রো উল্লেখ করেছিলেন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.