从条目中具有不同长度的字典创建数据框

时间:2013-11-01 21:59:10

标签: python pandas

假设我有一个包含10个键值对的字典。每个条目都有一个numpy数组。但是,对于所有这些数组,数组的长度并不相同。

如何创建一个数据框,其中每列包含不同的条目?

当我尝试:

pd.DataFrame(my_dict)

我明白了:

ValueError: arrays must all be the same length

有什么办法可以克服这个问题?我很高兴让Pandas使用NaN填充这些列以填入较短的条目。

9 个答案:

答案 0 :(得分:93)

在Python 3.x中:

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

In [7]: DataFrame(dict([ (k,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中:

d.items()替换为d.iteritems()

答案 1 :(得分:64)

这是一个简单的方法:

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

答案 2 :(得分:8)

一种整理语法的方法,但仍然与其他答案基本相同,如下所示:

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

在所有这些情况下,您必须小心检查哪些数据类型pandas将为您的列猜测。例如,包含任何NaN(缺失)值的列将转换为float。

答案 3 :(得分:3)

虽然这并没有直接回答OP的问题。我发现这是一个很好的解决方案,当我有不相等的数组,我想分享:

from pandas documentation

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

答案 4 :(得分:2)

您还可以将pd.concataxis=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

答案 5 :(得分: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个,建议您使用类似的方法来创建一个函数。

答案 6 :(得分:1)

pd.DataFrame([my_dict])可以!

答案 7 :(得分:0)

以下两行均能正常工作:

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的速度之比为4倍,这尤其在处理庞大的数据集(主要是具有大量列/功能)时尤其令人印象深刻。

答案 8 :(得分:0)

使用pandas.DataFramepandas.concat

  • 以下代码将从不均匀list的{​​{1}}到pandas.DataFrameconcat中创建DataFrames的{​​{1}},然后{列表理解中的数组。
    • 这是一种创建长度为不相等的dict的{​​{1}}的方法。
    • 对于相等长度的arrays,请使用DataFrame
arrays

使用pandas.DataFrameitertools.zip_longest

  • 对于长度不等的可迭代项,arraysdf = pd.DataFrame({'x1': x1, 'x2': x2, 'x3': x3})填充缺失值。
  • 需要解压缩zip生成器,因为import pandas as pd import numpy as np # create the uneven arrays mu, sigma = 200, 25 np.random.seed(365) x1 = mu + sigma * np.random.randn(10, 1) x2 = mu + sigma * np.random.randn(15, 1) x3 = mu + sigma * np.random.randn(20, 1) data = {'x1': x1, 'x2': x2, 'x3': x3} # create the dataframe df = pd.concat([pd.DataFrame(v, columns=[k]) for k, v in data.items()], axis=1) 构造函数不会解压缩它。
zip_longest

情节

fillvalue

enter image description here

数据框

DataFrame