Girişlerin farklı uzunluklara sahip olduğu bir sözlükten veri çerçevesi oluşturma


114

10 anahtar / değer çifti içeren bir sözlüğüm olduğunu varsayalım. Her girdi bir uyuşmuş dizi içerir. Ancak, dizinin uzunluğu hepsi için aynı değildir.

Her sütunun farklı bir girdi içerdiği bir veri çerçevesini nasıl oluşturabilirim?

Denediğimde:

pd.DataFrame(my_dict)

Alırım:

ValueError: arrays must all be the same length

Bunun üstesinden gelmenin bir yolu var mı? Pandaların NaNbu sütunları daha kısa girişler için doldurmasına izin vermekten mutluluk duyuyorum .

Yanıtlar:


132

Python 3.x'te:

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

Python 2.x'te:

yerine d.items()sahip d.iteritems().


Son zamanlarda aynı sorun üzerinde çalışıyordum ve bu sahip olduğumdan daha iyi! Unutulmaması gereken bir şey, NaN'lerle doldurmak, dtype serisini float64'e zorlayacaktır, bu da tamsayı matematik yapmanız gerekiyorsa sorunlu olabilir.
mattexx

her zaman soru sorabilirsin - pek çok kişi cevaplıyor
Jeff

yorumların önerdiği gibi MVCE'yi sağlamanız gerekiyor
Jeff

3
@germ önce Seriyi içe aktarmak isteyebilir veya pd.Series(...) ( import pandas as pdiçe aktarma bölümünde olduğu varsayılarak )
Nima Mousavi

5
Bu cevabın daha kısa versiyonu:pd.DataFrame({k: pd.Series(l) for k, l in d.items()})
user553965

82

İşte bunu yapmanın basit bir yolu:

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

'endekslemek' için başka seçenekler var mı?
sAguinaga

@sAguinaga Evet:, columnsancak bu zaten varsayılandır. Pandas belgelerine
Murmel

15

Sözdizimini düzeltmenin bir yolu, ancak yine de bu diğer cevaplarla aynı şeyi yapmanın bir yolu aşağıdadır:

>>> 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

Listeler için de benzer bir sözdizimi vardır:

>>> 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

Listeler için başka bir sözdizimi şudur:

>>> 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

Ek olarak sonucu transpoze etmeniz ve / veya sütun veri türlerini (float, integer, vb.) Değiştirmeniz gerekebilir.


3

Bu doğrudan OP'nin sorusuna cevap vermiyor. Eşit olmayan dizilerim olduğunda bunu benim durumum için mükemmel bir çözüm olarak buldum ve paylaşmak istiyorum:

pandaların belgelerinden

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

Ayrıca bir nesne listesiyle pd.concatbirlikte kullanabilirsiniz :axis=1pd.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

Aşağıdaki satırların her ikisi de mükemmel çalışıyor:

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

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

Ancak Jupyter'de% timeit ile, B'ye karşı A için 4x hız oranına sahibim, bu özellikle büyük bir veri kümesiyle çalışırken (çoğunlukla çok sayıda sütun / özellik ile) oldukça etkileyici.


1

Gösterilmesini istemiyorsanız NaNve iki belirli uzunluğunuz varsa, kalan her hücreye bir 'boşluk' eklemek de işe yarayacaktır.

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'den fazla uzunlukta girişiniz varsa, benzer bir yöntem kullanan bir işlev yapmanız önerilir.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.