दोनों के साथ एक उपयोगकर्ता के रूप में Rऔर python, मैंने इस प्रकार का प्रश्न एक दो बार देखा है।
आर में, उनके पास अंतर्निहित फ़ंक्शन है tidyrजिसे पैकेज कहा जाता है unnest। लेकिन Python( pandas) इस प्रकार के प्रश्न के लिए कोई अंतर्निहित कार्य नहीं है।
मुझे पता है कि objectकॉलम typeहमेशा pandas'फ़ंक्शन के साथ कनवर्ट करने के लिए डेटा को कठिन बनाते हैं । जब मुझे इस तरह का डेटा मिला, तो पहली बात जो मन में आई, वह थी 'चपटा' या स्तंभों को बेकार करना।
मैं इस प्रकार के प्रश्न के लिए उपयोग कर रहा हूं pandasऔर pythonकार्य कर रहा हूं । यदि आप उपरोक्त समाधानों की गति के बारे में चिंतित हैं, तो user3483203 के उत्तर की जांच करें, क्योंकि वह उपयोग कर रहा है 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.1
उदाहरण के लिए ए के अलावा हमारे पास ए 1 है ..... एक अगर हम अभी भी विधि ( विधि 2 ) का उपयोग करते हैं, तो हमारे लिए एक-एक करके स्तंभों को फिर से बनाना मुश्किल है।
समाधान: joinया एकल कॉलम mergeके indexबाद 'अनावश्यक' के साथ
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
बेस फंक्शन का उपयोग करते हुए विधि 7itertools 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निर्माता के साथ जांचें
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