Python 转换列表Dict';s到数据帧:熊猫
我正在做一些网页抓取,并以以下形式存储感兴趣的变量:Python 转换列表Dict';s到数据帧:熊猫,python,pandas,dictionary,dataframe,Python,Pandas,Dictionary,Dataframe,我正在做一些网页抓取,并以以下形式存储感兴趣的变量: a = {'b':[100, 200],'c':[300, 400]} 这是一个页面,其中有两个b,两个c。下一页可能有三个,我将它们存储为: b = {'b':[300, 400, 500],'c':[500, 600, 700]} 当我从dict列表中创建DataFrame时,我得到: import pandas as pd df = pd.DataFrame([a, b]) df b
a = {'b':[100, 200],'c':[300, 400]}
这是一个页面,其中有两个b
,两个c
。下一页可能有三个,我将它们存储为:
b = {'b':[300, 400, 500],'c':[500, 600, 700]}
当我从dict
列表中创建DataFrame
时,我得到:
import pandas as pd
df = pd.DataFrame([a, b])
df
b c
0 [100, 200] [300, 400]
1 [300, 400, 500] [500, 600, 700]
我期待的是:
df
b c
0 100 300
1 200 400
2 300 500
3 400 600
4 500 700
我可以在每次存储页面时创建一个
DataFrame
,并在末尾创建DataFrame
列表。然而,根据经验,这是非常昂贵的,因为构建数千个数据帧
,比从较低级别的构造函数(即dict
的列表)创建一个数据帧
要昂贵得多。在每个步骤中简单地合并字典怎么样
import pandas as pd
def merge_dicts(trg, src):
for k, v in src.items():
trg[k].extend(v)
a = {'b':[100, 200],'c':[300, 400]}
b = {'b':[300, 400, 500],'c':[500, 600, 700]}
merge_dicts(a, b)
print(a)
# {'c': [300, 400, 500, 600, 700], 'b': [100, 200, 300, 400, 500]}
print(pd.DataFrame(a))
# b c
# 0 100 300
# 1 200 400
# 2 300 500
# 3 400 600
# 4 500 700
为了清晰起见,请尝试以下更改键:
a = {'e':[100, 200],'f':[300, 400]}
b = {'e':[300, 400, 500],'f':[500, 600, 700]}
c = {'e':[300, 400, 500],'f':[500, 600, 700]}
listDicts = [a,b,c]
dd= {}
for x in listDicts:
for k in listDicts[0].keys():
try: dd[k] = dd[k] + x[k]
except: dd[k] = x[k]
df = pd.DataFrame(dd)
e f
0 100 300
1 200 400
2 300 500
3 400 600
4 500 700
5 100 300
6 200 400
7 300 500
8 400 600
9 500 700
理解FTW(可能不是最快的,但你能再多做些蟒蛇吗?):
编辑:
我被纠正了。它和其他一些方法一样快
import pandas as pd
import toolz
list_of_dicts = [{'b': [100, 200], 'c': [300, 400]},
{'b': [300, 400, 500], 'c': [500, 600, 700]}]
def extract(key):
return [item for x in list_of_dicts for item in x[key]]
def merge_dicts(trg, src):
for k, v in src.items():
trg[k].extend(v)
def approach_AlbertoGarciaRaboso():
df = pd.DataFrame({k: extract(k) for k in ['b', 'c']})
def approach_root():
df = pd.DataFrame(toolz.merge_with(lambda x: list(toolz.concat(x)), list_of_dicts))
def approach_Merlin():
dd = {}
for x in list_of_dicts:
for k in list_of_dicts[0].keys():
try: dd[k] = dd[k] + x[k]
except: dd[k] = x[k]
df = pd.DataFrame(dd)
def approach_MichaelHoff():
merge_dicts(list_of_dicts[0], list_of_dicts[1])
df = pd.DataFrame(list_of_dicts[0])
%timeit approach_AlbertoGarciaRaboso() # 1000 loops, best of 3: 501 µs per loop
%timeit approach_root() # 1000 loops, best of 3: 503 µs per loop
%timeit approach_Merlin() # 1000 loops, best of 3: 516 µs per loop
%timeit approach_MichaelHoff() # 100 loops, best of 3: 2.62 ms per loop
可能的副本?不完全是这样,但至少这两个问题彼此有着很强的相关性。迭代键和合并列表似乎是您想要的解决方案。您还需要
a
和b
命令吗?如果没有,您可以在从所有页面接收数据时继续将数据附加到dicta
,然后执行df=pd.DataFrame(a)
。您不能像这样对我的方法计时。我的函数修改给定的字典,因此您正在使用timeit创建非常长的列表。。。另一件事是整数列表(和dict)的性能明显长于2-3个元素。
import pandas as pd
import toolz
list_of_dicts = [{'b': [100, 200], 'c': [300, 400]},
{'b': [300, 400, 500], 'c': [500, 600, 700]}]
def extract(key):
return [item for x in list_of_dicts for item in x[key]]
def merge_dicts(trg, src):
for k, v in src.items():
trg[k].extend(v)
def approach_AlbertoGarciaRaboso():
df = pd.DataFrame({k: extract(k) for k in ['b', 'c']})
def approach_root():
df = pd.DataFrame(toolz.merge_with(lambda x: list(toolz.concat(x)), list_of_dicts))
def approach_Merlin():
dd = {}
for x in list_of_dicts:
for k in list_of_dicts[0].keys():
try: dd[k] = dd[k] + x[k]
except: dd[k] = x[k]
df = pd.DataFrame(dd)
def approach_MichaelHoff():
merge_dicts(list_of_dicts[0], list_of_dicts[1])
df = pd.DataFrame(list_of_dicts[0])
%timeit approach_AlbertoGarciaRaboso() # 1000 loops, best of 3: 501 µs per loop
%timeit approach_root() # 1000 loops, best of 3: 503 µs per loop
%timeit approach_Merlin() # 1000 loops, best of 3: 516 µs per loop
%timeit approach_MichaelHoff() # 100 loops, best of 3: 2.62 ms per loop