在多处理中将列表转换为数据框
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 的正确转换方法(可能还有更多方法):
- 将列名称作为列表的一部分,如下所示:(我只从您的集合中提取了前 2 个列)
df_list= [[ {"A":0 }, {"B": '2009-10-01'}],
[ {"A":1}, {"B":'2009-10-01'}]]
- 然后使用下面的代码,你可以转换为数据帧:
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
显式转换后,我们又回到了常规的旧列表。
我在 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 的正确转换方法(可能还有更多方法):
- 将列名称作为列表的一部分,如下所示:(我只从您的集合中提取了前 2 个列)
df_list= [[ {"A":0 }, {"B": '2009-10-01'}],
[ {"A":1}, {"B":'2009-10-01'}]]
- 然后使用下面的代码,你可以转换为数据帧:
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
显式转换后,我们又回到了常规的旧列表。