【问题标题】:Converting list Dict's to DataFrame: Pandas将列表 Dict 转换为 DataFrame:Pandas
【发布时间】:2016-12-02 02:59:38
【问题描述】:

我正在做一些网络抓取,并以以下形式存储感兴趣的变量:

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 的列表concat。然而,根据经验,这是非常昂贵的,因为构造数以千计的DataFrame 比从较低级别的构造函数(即dict 的列表)创建一个DataFrame 要昂贵得多。

【问题讨论】:

  • this question 可能重复?不完全是,但至少这两个问题彼此密切相关。
  • 遍历键和合并列表似乎是您想要的解决方案。
  • 您还需要ab dicts 吗?如果没有,您可以在从所有页面收到数据时继续将数据附加到dict a,然后执行df = pd.DataFrame(a)

标签: python pandas dictionary dataframe


【解决方案1】:

Comprehensions FTW(也许不是最快的,但你能得到更多的pythonic吗?):

import pandas as pd

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]]

df = pd.DataFrame({k: extract(k) for k in ['b', 'c']})

编辑:

我的立场是正确的。它与其他一些方法一样快。

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

【讨论】:

  • 你不能像这样给我的方法计时。我的函数修改了给定的字典,因此您正在使用 timeit 创建非常长的列表...另一件事是整数列表(和字典)的性能明显长于 2-3 个元素。
【解决方案2】:

为了清楚起见,试试这个更改键:

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

【讨论】:

    【解决方案3】:

    在每个步骤中简单地合并字典怎么样?

    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
    

    【讨论】:

      猜你喜欢
      • 2018-10-14
      • 1970-01-01
      • 2018-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多