我有一个很大的(ish)Series
字典,我想“扁平化”。为了测试/重现我的问题,我创建了一个具有类似结构的Series
:
>>> my_series = pd.Series([{'A': [1], 'B' : []}, {'A' : [1, 2], 'B' : [3, 4]}])
>>> my_series
0 {u'A': [1], u'B': []}
1 {u'A': [1, 2], u'B': [3, 4]}
dtype: object
下一步是将其转换为带有分层索引的“DataFrame”。我找到了一种功能正常的方法:
>>> pd.DataFrame(pd.DataFrame.from_dict(row, orient='index').stack() for row in my_series)
A B
0 1 0 1
0 1.0 NaN NaN NaN
1 1.0 2.0 3.0 4.0
这给了我想要的东西,但是在我的实际数据集上,它非常慢,每个列表中有0到4个元素的30,000行大约需要60秒,并使用大约8G的RAM。
我尝试使用map
模块进行并行multiprocessing
操作来加快速度,但我想在此问一下是否有更好的方法。
我可以在更合理的时间内取得与上述相同的结果吗?
答案 0 :(得分:1)
首先,由于您的词典位于基于熊猫的数据结构中,因此您可以创建DataFrame
而不是系列。
其次DataFrame
可以接受字典列表并为您构建预期结果。因此,如果您首先无法控制系列的构建,则只需将系列转换为列表并将其传递给DataFrame
:
In [10]: pd.DataFrame(list(my_series))
Out[10]:
A B
0 [1] []
1 [1, 2] [3, 4]
答案 1 :(得分:1)
您可以使用DataFrame
构造函数,但首先将Series
转换为numpy array
values
再转换为list
:
a = pd.DataFrame(my_series.values.tolist())
print (a)
A B
0 [1] []
1 [1, 2] [3, 4]
然后,对于flatennig,可以使用concat
与list comprehension
:
b = pd.concat([pd.DataFrame(a[x].values.tolist()) for x in a.columns], axis=1,keys=a.columns)
print (b)
A B
0 1 0 1
0 1 NaN NaN NaN
1 1 2.0 3.0 4.0
如果转换为numpy数组更快:
In [93]: %timeit pd.DataFrame(list(my_series))
1000 loops, best of 3: 550 µs per loop
In [94]: %timeit pd.DataFrame(my_series.values.tolist())
1000 loops, best of 3: 516 µs per loop
答案 2 :(得分:0)
<强>设置强>
my_series = pd.Series([{'A': [1], 'B' : []}, {'A' : [1, 2], 'B' : [3, 4]}])
df = pd.DataFrame.from_dict(s.tolist())
<强>解决方案强>
好的,有一个更快的解决方案。
idx = pd.MultiIndex.from_product([['A','B'],[0,1]])
pd.DataFrame(pd.DataFrame(df.values.flatten().tolist()).values.reshape(2,-1), columns=idx)
Out[1051]:
A B
0 1 0 1
0 1.0 NaN NaN NaN
1 1.0 2.0 3.0 4.0
旧解决方案
#Convert list elements to columns
df_A = df.A.apply(pd.Series).stack().unstack()
df_B = df.B.apply(pd.Series).stack().unstack()
#rename columns
df_A.columns = ['A_' + str(e) for e in df_A.columns]
df_B.columns = ['B_' + str(e) for e in df_B.columns]
#combine two dataframes
pd.concat([df_A,df_B],axis=1)
Out[973]:
A_0 A_1 B_0 B_1
0 1.0 NaN NaN NaN
1 1.0 2.0 3.0 4.0
<强>测试强>
%timeit pd.DataFrame(pd.DataFrame(df.values.flatten().tolist()).values.reshape(2,-1), columns=idx)
1000 loops, best of 3: 378 µs per loop
%timeit pd.concat([pd.DataFrame(df[x].values.tolist()) for x in df.columns], axis=1,keys=df.columns)
1000 loops, best of 3: 1.22 ms per loop