Rএবং উভয়ই একজন ব্যবহারকারী হিসাবে pythonআমি এই ধরণের প্রশ্নটি বেশ কয়েকবার দেখেছি।
আর, তারা প্যাকেজ থেকে বিল্ট-ইন ফাংশন আছে tidyrবলা unnest। কিন্তু মধ্যে Python(pandas ) এ এই ধরণের প্রশ্নের কোনও অন্তর্নির্মিত ফাংশন নেই।
আমি জানি objectকলামগুলি typeসবসময় ডেটাটিকে একটি pandas'ফাংশন দিয়ে রূপান্তর করতে শক্ত করে তোলে । আমি যখন এই জাতীয় ডেটা পেয়েছি তখন প্রথম যে বিষয়টি মনে পড়েছিল তা হ'ল চ্যাপ্টা করা বা কলামগুলি আনস্টন করা।
আমি এই ধরণের প্রশ্নের জন্য ব্যবহার করছি pandasএবং pythonফাংশন করছি। আপনি যদি উপরের সমাধানগুলির গতি সম্পর্কে উদ্বিগ্ন হন তবে ব্যবহারকারী 3483203 এর উত্তরটি পরীক্ষা করুন, যেহেতু তিনি ব্যবহার করছেন numpyএবং বেশিরভাগ সময় numpyদ্রুততর হয়। আমি প্রস্তাব দিচ্ছি Cpythonএবং numbaযদি আপনার ক্ষেত্রে গতি বিবেচনা করে।
পদ্ধতি 0 [প্যান্ডাস> = 0.25] পান্ডাস 0.25
থেকে শুরু করে , আপনার যদি কেবল একটি কলাম বিস্ফোরণ করতে হয় তবে আপনি ফাংশনটি ব্যবহার করতে পারেন :explode
df.explode('B')
A B
0 1 1
1 1 2
0 2 1
1 2 2
পদ্ধতি 1
apply + pd.Series (বুঝতে সহজ তবে পারফরম্যান্সের দিক দিয়ে সুপারিশ করা হয়নি))
df.set_index('A').B.apply(pd.Series).stack().reset_index(level=0).rename(columns={0:'B'})
Out[463]:
A B
0 1 1
1 1 2
0 2 1
1 2 2
পদ্ধতি 2 কনস্ট্রাক্টরের সাথে
ব্যবহার করে আপনার ডেটাফ্রেমটি পুনরায় তৈরি করুন (পারফরম্যান্সে ভাল, একাধিক কলামে ভাল নয়)repeatDataFrame
df=pd.DataFrame({'A':df.A.repeat(df.B.str.len()),'B':np.concatenate(df.B.values)})
df
Out[465]:
A B
0 1 1
0 1 2
1 2 1
1 2 2
পদ্ধতি ২.১
উদাহরণস্বরূপ এ ছাড়াও আমাদের কাছে এ .১ ..... একটি আমরা যদি এখনও উপরে পদ্ধতি ( পদ্ধতি 2 ) ব্যবহার করি তবে আমাদের পক্ষে কলামগুলি একে একে পুনরায় তৈরি করা শক্ত hard
সমাধান: joinবা mergeসঙ্গে indexপরে 'unnest' একক কলাম
s=pd.DataFrame({'B':np.concatenate(df.B.values)},index=df.index.repeat(df.B.str.len()))
s.join(df.drop('B',1),how='left')
Out[477]:
B A
0 1 1
0 2 1
1 1 2
1 2 2
আপনার যদি আগের মতো কলামের ক্রম দরকার reindexহয় তবে শেষে যুক্ত করুন।
s.join(df.drop('B',1),how='left').reindex(columns=df.columns)
পদ্ধতি 3
পুনরায় তৈরি করুনlist
pd.DataFrame([[x] + [z] for x, y in df.values for z in y],columns=df.columns)
Out[488]:
A B
0 1 1
1 1 2
2 2 1
3 2 2
যদি দুটি কলামের বেশি হয় তবে ব্যবহার করুন
s=pd.DataFrame([[x] + [z] for x, y in zip(df.index,df.B) for z in y])
s.merge(df,left_on=0,right_index=True)
Out[491]:
0 1 A B
0 0 1 1 [1, 2]
1 0 2 1 [1, 2]
2 1 1 2 [1, 2]
3 1 2 2 [1, 2]
পদ্ধতি 4
ব্যবহার করে reindex বাloc
df.reindex(df.index.repeat(df.B.str.len())).assign(B=np.concatenate(df.B.values))
Out[554]:
A B
0 1 1
0 1 2
1 2 1
1 2 2
#df.loc[df.index.repeat(df.B.str.len())].assign(B=np.concatenate(df.B.values))
পদ্ধতি 5
যখন তালিকায় কেবল অনন্য মান থাকে:
df=pd.DataFrame({'A':[1,2],'B':[[1,2],[3,4]]})
from collections import ChainMap
d = dict(ChainMap(*map(dict.fromkeys, df['B'], df['A'])))
pd.DataFrame(list(d.items()),columns=df.columns[::-1])
Out[574]:
B A
0 1 1
1 2 1
2 3 2
3 4 2
উচ্চ কার্যকারিতা জন্য 6 পদ্ধতি
ব্যবহার করে numpy:
newvalues=np.dstack((np.repeat(df.A.values,list(map(len,df.B.values))),np.concatenate(df.B.values)))
pd.DataFrame(data=newvalues[0],columns=df.columns)
A B
0 1 1
1 1 2
2 2 1
3 2 2
বেস ফাংশনটি ব্যবহার করে 7 পদ্ধতিitertools cycle এবং chain: খালি মজাদার জন্য খাঁটি অজগর সমাধান
from itertools import cycle,chain
l=df.values.tolist()
l1=[list(zip([x[0]], cycle(x[1])) if len([x[0]]) > len(x[1]) else list(zip(cycle([x[0]]), x[1]))) for x in l]
pd.DataFrame(list(chain.from_iterable(l1)),columns=df.columns)
A B
0 1 1
1 1 2
2 2 1
3 2 2
একাধিক কলামে সাধারণীকরণ
df=pd.DataFrame({'A':[1,2],'B':[[1,2],[3,4]],'C':[[1,2],[3,4]]})
df
Out[592]:
A B C
0 1 [1, 2] [1, 2]
1 2 [3, 4] [3, 4]
স্ব-ডিফ ফাংশন:
def unnesting(df, explode):
idx = df.index.repeat(df[explode[0]].str.len())
df1 = pd.concat([
pd.DataFrame({x: np.concatenate(df[x].values)}) for x in explode], axis=1)
df1.index = idx
return df1.join(df.drop(explode, 1), how='left')
unnesting(df,['B','C'])
Out[609]:
B C A
0 1 1 1
0 2 2 1
1 3 3 2
1 4 4 2
কলাম-ভিত্তিক আনস্টেস্টিং
উপরের সমস্ত পদ্ধতি উল্লম্ব আনস্টেস্টিং এবং বিস্ফোরণ সম্পর্কে কথা বলছে , আপনার যদি তালিকাটি অনুভূমিকভাবে ব্যয় করতে চান তবে pd.DataFrameকনস্ট্রাক্টরের সাথে পরীক্ষা করুন Check
df.join(pd.DataFrame(df.B.tolist(),index=df.index).add_prefix('B_'))
Out[33]:
A B C B_0 B_1
0 1 [1, 2] [1, 2] 1 2
1 2 [3, 4] [3, 4] 3 4
আপডেট ফাংশন
def unnesting(df, explode, axis):
if axis==1:
idx = df.index.repeat(df[explode[0]].str.len())
df1 = pd.concat([
pd.DataFrame({x: np.concatenate(df[x].values)}) for x in explode], axis=1)
df1.index = idx
return df1.join(df.drop(explode, 1), how='left')
else :
df1 = pd.concat([
pd.DataFrame(df[x].tolist(), index=df.index).add_prefix(x) for x in explode], axis=1)
return df1.join(df.drop(explode, 1), how='left')
পরীক্ষা আউটপুট
unnesting(df, ['B','C'], axis=0)
Out[36]:
B0 B1 C0 C1 A
0 1 2 1 2 1
1 3 4 3 4 2