एक शब्दकोश से डेटाफ्रेम बनाना जहां प्रविष्टियों की लंबाई अलग-अलग होती है


114

मान लें कि मेरे पास 10 कुंजी-मूल्य वाले युग्मों के साथ एक शब्दकोश है। प्रत्येक प्रविष्टि एक सुव्यवस्थित सरणी रखती है। हालाँकि, सरणी की लंबाई उन सभी के लिए समान नहीं है।

मैं एक डेटाफ्रेम कैसे बना सकता हूं जहां प्रत्येक कॉलम एक अलग प्रविष्टि रखता है?

जब मैं कोशिश करता हूं:

pd.DataFrame(my_dict)

मुझे मिला:

ValueError: arrays must all be the same length

इसे दूर करने का कोई तरीका? मुझे खुशी है कि पंडों NaNने छोटी प्रविष्टियों के लिए उन कॉलमों को पैड करने के लिए उपयोग किया।

जवाबों:


132

पायथन 3.x में:

In [6]: d = dict( A = np.array([1,2]), B = np.array([1,2,3,4]) )

In [7]: pd.DataFrame(dict([ (k,pd.Series(v)) for k,v in d.items() ]))
Out[7]: 
    A  B
0   1  1
1   2  2
2 NaN  3
3 NaN  4

पायथन में 2.x:

के d.items()साथ बदलें d.iteritems()


मैं हाल ही में इसी समस्या पर काम कर रहा था, और जो मेरे पास था उससे यह बेहतर है! नोट करने के लिए एक बात, NaNs के साथ पैडिंग श्रृंखला dtype को फ्लोट64 में ले जाएगी, जो कि पूर्णांक गणित करने की आवश्यकता होने पर समस्याग्रस्त हो सकती है।
1

यू हमेशा एक सवाल पूछ सकते हैं - बहुत से लोग उन्हें जवाब देते हैं
जेफ

आपको MVCE प्रदान करने की आवश्यकता है क्योंकि टिप्पणियों का सुझाव है
जेफ

3
@ आप पहले श्रृंखला आयात करना चाहते हैं या ऐसा कुछ कर सकते हैं pd.Series(...) ( import pandas as pdआयात अनुभाग में मानकर )
नीमा मौसवी

5
इस उत्तर का अधिक कॉम्पैक्ट संस्करण:pd.DataFrame({k: pd.Series(l) for k, l in d.items()})
user553965

82

यहाँ एक आसान तरीका है कि:

In[20]: my_dict = dict( A = np.array([1,2]), B = np.array([1,2,3,4]) )
In[21]: df = pd.DataFrame.from_dict(my_dict, orient='index')
In[22]: df
Out[22]: 
   0  1   2   3
A  1  2 NaN NaN
B  1  2   3   4
In[23]: df.transpose()
Out[23]: 
    A  B
0   1  1
1   2  2
2 NaN  3
3 NaN  4

क्या 'सूचकांक' के अन्य विकल्प हैं?
sAguinaga

@sAguinaga हाँ:, columnsलेकिन यह पहले से ही डिफ़ॉल्ट है। पांडा प्रलेखन
Murmel

15

अपने सिंटैक्स को बाँधने का एक तरीका है, लेकिन फिर भी अनिवार्य रूप से इन अन्य उत्तरों के समान ही है, नीचे है:

>>> mydict = {'one': [1,2,3], 2: [4,5,6,7], 3: 8}

>>> dict_df = pd.DataFrame({ key:pd.Series(value) for key, value in mydict.items() })

>>> dict_df

   one  2    3
0  1.0  4  8.0
1  2.0  5  NaN
2  3.0  6  NaN
3  NaN  7  NaN

एक समान वाक्यविन्यास सूची के लिए भी मौजूद है:

>>> mylist = [ [1,2,3], [4,5], 6 ]

>>> list_df = pd.DataFrame([ pd.Series(value) for value in mylist ])

>>> list_df

     0    1    2
0  1.0  2.0  3.0
1  4.0  5.0  NaN
2  6.0  NaN  NaN

सूचियों के लिए एक और वाक्य रचना है:

>>> mylist = [ [1,2,3], [4,5], 6 ]

>>> list_df = pd.DataFrame({ i:pd.Series(value) for i, value in enumerate(mylist) })

>>> list_df

   0    1    2
0  1  4.0  6.0
1  2  5.0  NaN
2  3  NaN  NaN

आपको अतिरिक्त रूप से परिणाम बदलना होगा और / या कॉलम डेटा प्रकार (फ्लोट, पूर्णांक, आदि) को बदलना होगा।


3

जबकि यह सीधे ओपी के सवाल का जवाब नहीं देता है। मुझे अपने मामले के लिए एक उत्कृष्ट समाधान मिला जब मेरे पास असमान सरणियाँ थीं और मैं साझा करना चाहूंगा:

पांडा प्रलेखन से

In [31]: d = {'one' : Series([1., 2., 3.], index=['a', 'b', 'c']),
   ....:      'two' : Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])}
   ....: 

In [32]: df = DataFrame(d)

In [33]: df
Out[33]: 
   one  two
a    1    1
b    2    2
c    3    3
d  NaN    4

3

आप वस्तुओं की सूची pd.concatके axis=1साथ भी उपयोग कर सकते pd.Seriesहैं:

import pandas as pd, numpy as np

d = {'A': np.array([1,2]), 'B': np.array([1,2,3,4])}

res = pd.concat([pd.Series(v, name=k) for k, v in d.items()], axis=1)

print(res)

     A  B
0  1.0  1
1  2.0  2
2  NaN  3
3  NaN  4

2

निम्नलिखित दोनों लाइनें पूरी तरह से काम करती हैं:

pd.DataFrame.from_dict(df, orient='index').transpose() #A

pd.DataFrame(dict([ (k,pd.Series(v)) for k,v in df.items() ])) #B (Better)

लेकिन Jupyter पर% timeit के साथ, मुझे B बनाम A के लिए 4x गति का अनुपात मिला है, जो विशेष रूप से एक विशाल डेटा सेट (मुख्य रूप से बड़ी संख्या में कॉलम / सुविधाओं के साथ) के साथ काम करते समय काफी प्रभावशाली है।


1

यदि आप इसे दिखाना नहीं चाहते हैं NaNऔर आपके पास दो विशेष लंबाई हैं, तो प्रत्येक शेष सेल में एक 'स्पेस' जोड़ना भी काम करेगा।

import pandas

long = [6, 4, 7, 3]
short = [5, 6]

for n in range(len(long) - len(short)):
    short.append(' ')

df = pd.DataFrame({'A':long, 'B':short}]
# Make sure Excel file exists in the working directory
datatoexcel = pd.ExcelWriter('example1.xlsx',engine = 'xlsxwriter')
df.to_excel(datatoexcel,sheet_name = 'Sheet1')
datatoexcel.save()

   A  B
0  6  5
1  4  6
2  7   
3  3   

यदि आपके पास प्रविष्टियों की 2 से अधिक लंबाई है, तो एक फ़ंक्शन बनाने के लिए सलाह दी जाती है जो एक समान विधि का उपयोग करता है।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.