列表中有很多字典VS字典,列表很少?

时间:2015-05-29 06:51:58

标签: python pandas dataset

我正在使用像这样的数据集进行一些练习:

列出了许多词典

users = [
    {"id": 0, "name": "Ashley"},
    {"id": 1, "name": "Ben"},
    {"id": 2, "name": "Conrad"},
    {"id": 3, "name": "Doug"},
    {"id": 4, "name": "Evin"},
    {"id": 5, "name": "Florian"},
    {"id": 6, "name": "Gerald"}
]

包含少量列表的词典

users2 = {
    "id": [0, 1, 2, 3, 4, 5, 6],
    "name": ["Ashley", "Ben", "Conrad", "Doug","Evin", "Florian", "Gerald"]
}

Pandas数据框

import pandas as pd
pd_users = pd.DataFrame(users)
pd_users2 = pd.DataFrame(users2)
print pd_users == pd_users2

问题:

  1. 我应该像用户一样构建数据集,还是像user2一样构建数据集?
  2. 是否存在性能差异?
  3. 比另一个更可读吗?
  4. 我应该遵循标准吗?
  5. 我通常将这些转换为pandas数据帧。当我这样做时,两个版本都是相同的......对吗?
  6. 每个元素的输出都是正确的,所以如果我和熊猫df一起工作并不重要吗?

6 个答案:

答案 0 :(得分:26)

这与column oriented databases与面向行有关。您的第一个示例是面向行的数据结构,第二个示例是面向列的。在Python的特定情况下,使用slots可以使第一个更高效,这样就不需要为每一行复制列的字典。

哪种形式更好地取决于您对数据的处理方式;例如,如果您只访问所有行,则面向行是自然的。同时以列为导向可以更好地利用缓存,例如当您在特定字段中搜索时(在Python中,这可能会因为大量使用引用而减少;类似array的类型可以优化)。传统的面向行的数据库经常使用面向列的排序索引来加速查找,并且了解这些技术后,您可以使用键值存储实现任何组合。

Pandas确实将您的示例转换为相同的格式,但转换本身对于面向行的结构来说更昂贵,因为必须读取每个单独的字典。所有这些成本可能都很小。

在您的示例中有第三个选项不明显:在这种情况下,您只有两列,其中一列是从0开始的连续范围内的整数ID。这可以按条目本身的顺序存储,这意味着您可以在名为users2['name']的列表中找到整个结构;但值得注意的是,没有他们的位置,条目是不完整的。该列表使用enumerate()转换为行。数据库通常也有这种特殊情况(例如,sqlite rowid)。

通常,从保持代码合理的数据结构开始,只有在了解用例并且存在可衡量的性能问题时才进行优化。像熊猫这样的工具可能意味着大多数项目都能正常运行而不需要微调。

答案 1 :(得分:6)

用户

  1. 当您需要添加一些新用户时,只需填写所有用户详细信息的新dict并附加

  2. 可以像@StevenRumbalski建议的那样轻松排序

  3. 搜索很容易

  4. 随着记录的增长,这更加紧凑,易于管理(对于一些非常多的记录,我认为我们需要的东西也比用户更好)

  5. <强> Users2

    1. 我个人第一次看到这个,如果我有大量的记录,我就不会接近这个。
    2. PS:但我想了解users2优于users的优势     再一个不错的问题

答案 2 :(得分:5)

查找时间复杂度 -

  • 列表 - O(n)
  • Dicts - O(1)

但如果您的数据不是那么大而且现代的处理器非常有效,那么这并不会造成太大的伤害。
您应该选择查找语法清晰易读的内容(可读性很重要) 第一个选项非常合适,因为变量是用户的集合(已经分配了id),而第二个选项只是用户名和ID的集合。

答案 3 :(得分:4)

一般而言,

users实际上是user元素的集合。因此,将user元素定义为独立实体会更好。所以你的第一个选择是正确的。

答案 4 :(得分:4)

关于熊猫方面的一些答案:

  1. 两个数据帧确实相同并且是面向列的,这很好,因为当每列中的数据是同类的时,pandas效果最好(即数字可以存储为int和float)。首先使用pandas的一个关键原因是你可以进行比纯python快几个数量级的矢量化数值运算 - 但是当数据属于异构类型时,这依赖于柱状组织。
  2. 如果您愿意,您可以pd_users.T进行转置,然后会看到(通过info()dtypes)然后将所有内容存储为通用对象,因为该列包含字符串和数字。
  3. 转换后,您可以执行pd_users.set_index('id'),以便您的数据框本质上是以id为键的字典。反之亦然name
  4. 在使用大熊猫时,更改索引,然后更改它们,转置,子集等非常常见(通常非常快),所以通常没有必要过多考虑结构在开始。只需根据需要随时更改即可。
  5. 这可能是在切线上下降,但是比上面提到的更简单的熊猫可能是Series而不是DataFrame。系列本质上是数据帧的一列,虽然它实际上只是一个带索引的一维数据数组(&#34;键&#34;)。
  6. 快速演示(使用df作为数据框名称,通用约定):

    >>> df.set_index('name')
    
             id
    name       
    Ashley    0
    Ben       1
    Conrad    2
    Doug      3
    Evin      4
    Florian   5
    Gerald    6
    
    >>> df.set_index('name').T
    
    name  Ashley  Ben  Conrad  Doug  Evin  Florian  Gerald
    id         0    1       2     3     4        5       6
    
    >>> df.set_index('name').loc['Doug']
    
    id    3
    Name: Doug, dtype: int64
    

答案 5 :(得分:1)

字典列表的第一个选项会因为很少的原因而更好。 List确实提供了诸如EXTEND,APPENT,PUSH之类的方法,这些方法不适用于词典。