【问题标题】:How to convert a list of dictionaries containing equal length lists into a dataframe without using a for loop如何在不使用 for 循环的情况下将包含等长列表的字典列表转换为数据框
【发布时间】:2019-06-27 20:19:19
【问题描述】:

我有一个由列表组成的字典列表(请参阅下面的示例代码)。我想做的是在不使用 for 循环的情况下用这些创建一个数据框。任何其他更快的方法都会很好。

ls = [ dict[lists], dict[lists], ... ]

最初我只是遍历字典列表并在列表理解中调用数据框对象,然后将它们连接起来。请参阅下面的代码。但这对于我拥有的字典数量来说相当慢。

temp_data_m1 = [{'x': np.random.rand(9).tolist(), 'y': np.random.rand(9).tolist(), 'z': np.random.rand(9).tolist()}]*50    
data_reshuffled1 = pd.concat([pd.DataFrame(dict_) for dict_ in temp_data_m1]).reset_index()

有没有办法在不使用 for 循环的情况下以更快的方式实现这一目标?

【问题讨论】:

  • 你是说不想循环,因为你认为不循环会更快?
  • 您是在为每个连续的字典添加更多行还是更多列?最终的 df 是什么样的?
  • @Jacob 我认为有更好更快的功能来做到这一点
  • @run-out 我只为每个连续的字典添加更多行
  • 如果您必须访问集合中的每个项目,假设您不打算使用低级别的iternext 功能,则必须循环。 (我在“循环”的定义中包含了 list comp 和 while 循环。)

标签: python python-3.x pandas dataframe dictionary


【解决方案1】:

您可以在字典推导中使用嵌套列表推导来首先转换您的原始数据。这假定temp_data_m1 中的每个项目都具有相同的字典键。

# Sample data.
temp_data_m1 = [
    {'x': np.random.rand(3).tolist(), 
     'y': np.random.rand(3).tolist(), 
     'z': np.random.rand(3).tolist()}] * 2   

cols = temp_data_m1[0].keys()
df = pd.DataFrame(
    {col: [val for group in temp_data_m1 for val in group[col]] 
     for col in cols}
)
>>> df
          x         y         z
0  0.348319  0.404375  0.817278
1  0.887448  0.438613  0.368390
2  0.971582  0.533209  0.119674
3  0.348319  0.404375  0.817278
4  0.887448  0.438613  0.368390
5  0.971582  0.533209  0.119674

时间

temp_data_m1 = [
    {'x': np.random.rand(3).tolist(), 
     'y': np.random.rand(3).tolist(), 
     'z': np.random.rand(3).tolist()}] * 20000

%%timeit 
cols = temp_data_m1[0].keys()
pd.DataFrame({col: [val for group in temp_data_m1 for val in group[col]] 
              for col in cols})
# output: 22.8 ms ± 849 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit pd.concat([pd.DataFrame(dict_) for dict_ in temp_data_m1]).reset_index(drop=True)
# output: 11.6 s ± 396 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

【讨论】:

  • 是的。这种方法在迄今为止建议的方法中效果最快。我想我会坚持这个。谢谢@亚历山大
【解决方案2】:

我认为您仍然需要循环,但使用本机列表和字典消除了 pd.DataFrame / concat 开销,并且会明显更快。

x_li = []
y_li = []
z_li = []

for l in ls: 
    x_li = x_li + l[0]['x']
    y_li = y_li + l[0]['y']
    z_li = z_li + l[0]['z']

dt = {'x': x_li, 'y': y_li, 'z': z_li}

df = pd.DataFrame(data=dt)

print(df)

           x         y         z
0   0.407243  0.064404  0.994289
1   0.778702  0.689556  0.246598
2   0.222480  0.236671  0.792531
3   0.114732  0.517506  0.901426
4   0.535884  0.138807  0.034585
5   0.621681  0.963316  0.628685
6   0.643132  0.994186  0.084340
7   0.167652  0.430170  0.344222
8   0.212579  0.649676  0.231918
9   0.704128  0.509263  0.047317
10  0.409379  0.939604  0.749458
11  0.029804  0.909334  0.520931
12  0.090505  0.834817  0.603464
13  0.837209  0.394173  0.877899
14  0.344467  0.602398  0.791664
15  0.077600  0.160189  0.237363
16  0.814201  0.104583  0.428033
17  0.899438  0.498138  0.855949
18  0.713373  0.732715  0.508276
19  0.211193  0.471923  0.526867
20  0.548586  0.136339  0.863532
21  0.041740  0.315708  0.116254
22  0.943269  0.056732  0.498985
23  0.085343  0.242628  0.039939
24  0.070387  0.114533  0.790064
25  0.568233  0.323008  0.811011
26  0.704781  0.221614  0.496521
27  0.089998  0.395631  0.703831
28  0.097087  0.012521  0.863149
29  0.731969  0.736039  0.147671
30  0.068417  0.117126  0.503902
31  0.487064  0.869781  0.677574
32  0.340297  0.633361  0.277859
33  0.141047  0.419666  0.193531
34  0.295001  0.845972  0.473824
35  0.217506  0.011523  0.717565
36  0.497627  0.059094  0.052230
37  0.658364  0.645356  0.712826
38  0.485345  0.600351  0.346634
39  0.395588  0.513874  0.797076
40  0.864188  0.786392  0.279711
41  0.979751  0.256491  0.305805
42  0.454343  0.954908  0.636447
43  0.279274  0.826389  0.891240
44  0.226816  0.222137  0.665129

【讨论】:

    猜你喜欢
    • 2020-08-16
    • 2019-04-21
    • 1970-01-01
    • 2019-10-11
    • 2023-01-19
    • 2018-10-10
    • 2022-11-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多