दोनों के साथ एक उपयोगकर्ता के रूप में 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 कंस्ट्रक्टर के साथ
प्रयोग करके , अपना डेटाफ़्रेम पुनः बनाएं (प्रदर्शन में अच्छा, कई कॉलम में अच्छा नहीं)repeat
DataFrame
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