【问题标题】:How to convert a big list of dictionaries into a pandas dataframe of this format?如何将大量字典转换为这种格式的熊猫数据框?
【发布时间】:2021-06-17 07:23:30
【问题描述】:

我有一个很大的字典列表,可以放入以下两种格式之一:

[{'cqug90j': [0, 1]},
 {'cqug90k': [7, 10]},
 {'cqug90z': [-3, 0]},
 {'cqug91c': [2, 9]}]
    
[{'cqug90j': {0, 1}},
 {'cqug90k': {7, 10}},
 {'cqug90z': {-3, 0}},
 {'cqug91c': {2, 9}}]

我需要转换成熊猫数据框

我的列表包含 400 万个这样的字典。您能否详细说明获取我想要的数据框的有效方法?

更新:我的列表也可以放入下面的表格中。

[{'cqug90j': {'var1': 0, 'var2': 1}},
 {'cqug90k': {'var1': 7, 'var2': 10}},
 {'cqug90z': {'var1': -3, 'var2': 0}},
 {'cqug91c': {'var1': 2, 'var2': 9}}]

【问题讨论】:

  • 集合是无序的。如果你有{'cqug90j': {0, 1}},你不能保证哪个来自var1,哪个来自var2,除非你打算对值进行排序。
  • @QuangHoang 所以我别无选择,只能{'cqug90j': [0, 1]} ^^。
  • @LEAnhDung--您是否希望较小的始终进入 var1 而较大的进入 var2?这是您示例中的模式,但它是否普遍适用?如果为 True,则它提供了一种可预测的方式来处理集合。
  • @DarrylG 遗憾的是,我的列表没有这样的属性。
  • @QuangHoang 我还更新了列表的可能格式。看看能不能提高速度。

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


【解决方案1】:

最简单的方法是对您的数据进行预处理,以获取正确的格式。 一个字典,其中键是您的列名,值是您的变量。

data = [
    dict(id='cqug90j', var1=0, var2=1),
    dict(id='cqug90k', var1=7, var2=10)
    ...
    ...
]

然后你可以使用pd.DataFrame.from_dict(data)。 即使对于数百万个值,这也应该只需要几秒钟的时间来处理。

示例

  • 以您的(第一个)指定格式生成任意数量的样本:
def generate_data(size=4_000_000):
    data = []
    iterator = product('abcdefghijklmnopqrstuvwxyz', repeat=6)

    start_time = time.perf_counter()
    while len(data) < size:
        data.append({''.join(next(iterator)): [np.random.randint(-256, 256), np.random.randint(-256, 256)]})
    print(f"Generated: {len(data):,d} items in {time.perf_counter() - start_time:5.2f}s")
    return data

This would take about ~30 seconds on my laptop.

  • 对数据进行预处理以使它们具有良好的形式
def reprocess(data):
    start_time = time.perf_counter()
    data = [dict(id=key, var1=var1, var2=var2) for dictionary in data for key, (var1, var2) in dictionary.items()]
    print(f"Reprocessed: {len(data):,d} items in {time.perf_counter() - start_time:5.2f}s")
    return data

有趣的是:

data = [dict(id=key, var1=var1, var2=var2) for dictionary in data for key, (var1, var2) in dictionary.items()]

这是一个列表推导等于:

data = []
for dictionary in data:
    for key, (var1, var2) in dictionary.items():
        data.append(dict(id=key, var1=var1, var2=var2))

Time taken about 2 seconds.

  • 生成熊猫数据框
def generate_dataframe(data):
    start_time = time.perf_counter()
    df = pd.DataFrame.from_dict(data)
    print(f"Generate df: {len(df):,d} items in {time.perf_counter() - start_time:5.2f}s")
    return df

Which takes about 5 seconds on my device.

完整代码运行

if __name__ == '__main__':
    data = generate_data(size=4_000_000)
    data = reprocess(data)
    df = generate_dataframe(data)
    print(f"\n{df.head()}", end="\n\n")

然后输出:

Generated: 4,000,000 items in 30.75s
Reprocessed: 4,000,000 items in  1.47s
Generate df: 4,000,000 items in  3.70s

       id  var1  var2
0  aaaaaa   173  -191
1  aaaaab   238   -60
2  aaaaac   -59   -25
3  aaaaad  -225   236
4  aaaaae   137   -18

结论

将 400 万个项目更改为一个数据框所需的总时间约为 6 秒。我不确定你是否需要它更快。但我认为这是一个好的开始。

【讨论】:

    【解决方案2】:

    对于海量数据,我会使用生成器:

    l = [
        {"cqug90j": {"var1": 0, "var2": 1}},
        {"cqug90k": {"var1": 7, "var2": 10}},
        {"cqug90z": {"var1": -3, "var2": 0}},
        {"cqug91c": {"var1": 2, "var2": 9}},
    ]
    
    
    def get_data(l):
        for d in l:
            k, d2 = d.popitem()
            yield k, d2["var1"], d2["var2"]
    
    
    df = pd.DataFrame(get_data(l), columns=["id", "var1", "var2"])
    print(df)
    

    打印:

            id  var1  var2
    0  cqug90j     0     1
    1  cqug90k     7    10
    2  cqug90z    -3     0
    3  cqug91c     2     9
    

    【讨论】:

      猜你喜欢
      • 2021-06-16
      • 2019-07-18
      • 2018-07-14
      • 2019-05-07
      • 2020-12-01
      • 1970-01-01
      • 2023-03-10
      • 2021-08-18
      相关资源
      最近更新 更多