假设我有一个包含10个键值对的字典。每个条目都有一个numpy数组。但是,对于所有这些数组,数组的长度并不相同。
如何创建一个数据框,其中每列包含不同的条目?
当我尝试:
pd.DataFrame(my_dict)
我明白了:
ValueError: arrays must all be the same length
有什么办法可以克服这个问题?我很高兴让Pandas使用NaN
填充这些列以填入较短的条目。
答案 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的问题。我发现这是一个很好的解决方案,当我有不相等的数组,我想分享:
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.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
答案 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.DataFrame
和pandas.concat
list
的{{1}}到pandas.DataFrame
的concat
中创建DataFrames
的{{1}},然后{列表理解中的数组。
dict
的{{1}}的方法。arrays
,请使用DataFrame
arrays
pandas.DataFrame
和itertools.zip_longest
arrays
用df = pd.DataFrame({'x1': x1, 'x2': x2, 'x3': x3})
填充缺失值。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
DataFrame