在多处理中将列表转换为数据框

Converting list to dataframe in multiprocessing

我在 python 中使用多处理来提高代码的性能。 我没有将结果直接附加到数据框中,而是使用了一个通用列表。

df_list = mp.Manager().list()

这些值是通过不同的过程计算并附加到上面的列表中的。

lock.acquire()
    try:
        temp = [a, b, c, d, e, f, g, h, i, j, k, l, m, n]
        df_list.append(temp)
    finally:
        lock.release()

字母表是包含不同值的变量。

子进程终止后,列表包含以下值:

print(df_list)
[[0, '2009-10-01', '2010-01-01', 3, 3, 1, 0.25, 0.9, 6, 100000, 101866.70524177742, 7.68, 100000, 0.0], 
 [1, '2009-10-01', '2010-01-01', 5, 7, 2, 0.25, 0.4, 8, 100000, 101866.70524177742, 9.32, 100000, 0.0]] 

现在,我需要将列表转换为数据框。

cols = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N"]
df = pd.DataFrame(df_list, columns = cols) 

但是,我收到以下错误:

ValueError                                Traceback (most recent call last)
~\Desktop\Temp\Python\calculate.py in <module>
    469     print(df_list)
    470
--> 471     df = pd.DataFrame(df_list, columns = cols)
    472

~\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\frame.py in __init__(self, data, index, columns, dtype, copy)
    466                                    dtype=values.dtype, copy=False)
    467             else:
--> 468                 raise ValueError('DataFrame constructor not properly called!')
    469
    470         NDFrame.__init__(self, mgr, fastpath=True)

如果我做错了什么,请告诉我。

编辑: 如果我们用标准列表替换列表,它就可以工作(也如评论中所述)。但是,在多进程中,我们需要一个管理器列表来跨进程共享。

此外,我找到了一个解决方法,它似乎有效:

simple_list = []
for l in df_list:
    simple_list.append(l)
df = pd.DataFrame(simple_list, columns = cols)

但是,如您所见,这并不是一种非常优雅的做事方式。 尽管如此,问题仍然存在——为什么我不能一步将经理列表转换为数据框。可能是我做错了什么?

我知道以下从列表到 Dataframe 的正确转换方法(可能还有更多方法):

  1. 将列名称作为列表的一部分,如下所示:(我只从您的集合中提取了前 2 个列)
    df_list= [[ {"A":0 }, {"B": '2009-10-01'}],
        [ {"A":1}, {"B":'2009-10-01'}]]
  1. 然后使用下面的代码,你可以转换为数据帧:
    df = pd.DataFrame(df_list)

它在这里工作正常(当我使用标准 list 时):

In [1]: import pandas as pd                                                                              

In [2]: df_list = [[0, '2009-10-01', '2010-01-01', 3, 3, 1, 0.25, 0.9, 6, 100000, 101866.70524177742, 7.6
   ...: 8, 100000, 0.0],  
   ...:  [1, '2009-10-01', '2010-01-01', 5, 7, 2, 0.25, 0.4, 8, 100000, 101866.70524177742, 9.32, 100000,
   ...:  0.0]]

In [3]: cols = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N"]

In [4]: df = pd.DataFrame(df_list, columns = cols)                                                       
Out[4]: 
   A           B           C  D  E  F     G    H  I       J              K     L       M    N
0  0  2009-10-01  2010-01-01  3  3  1  0.25  0.9  6  100000  101866.705242  7.68  100000  0.0
1  1  2009-10-01  2010-01-01  5  7  2  0.25  0.4  8  100000  101866.705242  9.32  100000  0.0

所以问题出在使用代理上。解决方案是在使用它创建 DataFrame 之前 将其转换 为列表。观察:

In [1]: import multiprocessing as mp

In [2]: proxy = mp.Manager().list([1,2,3])
Out[2]: <ListProxy object, typeid 'list' at 0x8042e5710>

In [3]: reallist = list(proxy)
Out[3]: [1, 2, 3]

In [4]: type(reallist)
Out[4]: list

显式转换后,我们又回到了常规的旧列表。