簡體   English   中英

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

[英]List with many dictionaries VS dictionary with few lists?

我正在用數據集做一些練習:

列出了許多詞典

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

熊貓數據幀

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

問題:

  1. 我應該像用戶或用戶2那樣構建數據集嗎?
  2. 是否存在性能差異?
  3. 一個比另一個更可讀嗎?
  4. 我應該遵循標准嗎?
  5. 我通常將這些轉換為pandas數據幀。 當我這樣做時,兩個版本都是相同的......對嗎?
  6. 每個元素的輸出都是正確的,所以如果我使用panda df是對的並不重要嗎?

這涉及面向列的數據庫與面向行的數據庫 您的第一個示例是面向行的數據結構,第二個示例是面向列的。 在Python的特定情況下,第一個使用插槽可以顯着提高效率,這樣就不需要為每一行復制列的字典。

哪種形式更好地取決於您對數據的處理方式; 例如,如果您只訪問所有行,則面向行是自然的。 面向列的同時可以更好地使用緩存,例如當你在特定字段中搜索時(在Python中,這可能會通過大量使用引用來減少;像數組這樣的類型可以優化它)。 傳統的面向行的數據庫經常使用面向列的排序索引來加速查找,並且了解這些技術后,您可以使用鍵值存儲實現任何組合。

Pandas確實將您的示例轉換為相同的格式,但轉換本身對於面向行的結構來說更昂貴,因為必須讀取每個單獨的字典。 所有這些成本可能都很小。

在您的示例中有第三個選項不明顯:在這種情況下,您只有兩列,其中一列是從0開始的連續范圍內的整數ID。這可以按條目本身的順序存儲,這意味着整個結構將在您稱為users2['name']的列表中找到; 但值得注意的是,沒有他們的位置,條目是不完整的。 該列表使用enumerate()轉換為行。 數據庫通常也有這種特殊情況(例如,sqlite rowid )。

通常,從保持代碼合理的數據結構開始,只有在了解用例並且存在可測量的性能問題時才進行優化。 像熊貓這樣的工具可能意味着大多數項目都能正常運行而不需要微調。

用戶

  1. 當您需要附加一些新用戶時,只需創建所有用戶詳細信息的新dict並附加它

  2. 像@StevenRumbalski建議的那樣可以輕松排序

  3. 搜索會很容易

  4. 隨着記錄的增長,這更加緊湊,易於管理(對於一些非常多的記錄,我認為我們需要比用戶更好的東西)

Users2

  1. 我個人第一次看到這個,如果我有大量的記錄,我不會接近這個。

PS:不過,我想了解的優勢users2users再次一個很好的問題

查詢的時間復雜度 -

  • 清單 - O(n)
  • Dicts - O(1)

但是,如果您的數據不是那么大並且現代處理器非常有效,那么這不會有太大影響。
你應該選擇查找語法清晰可讀的方法(可讀性很重要)。
第一個選項非常合適,因為變量是用戶的集合(已經分配了id),而第二個選項只是用戶名和id的集合。

users在一般意義上其實是集合user的元素。 因此,最好將user元素定義為獨立實體。 所以你的第一個選擇是正確的。

關於熊貓方面的一些答案:

  1. 兩個數據幀確實是相同的並且是面向列的,這很好,因為當每列中的數據是同類的時,pandas最有效(即數字可以存儲為int和float)。 首先使用pandas的一個關鍵原因是你可以進行比純python快幾個數量級的矢量化數值運算 - 但是當數據是異構類型時,這依賴於柱狀組織。
  2. 你可以做pd_users.T轉置,如果你願意,然后會看到(通過info()dtypes )然后將所有內容存儲為通用對象,因為該列包含字符串和數字。
  3. 轉換后,您可以執行pd_users.set_index('id')以便您的數據pd_users.set_index('id')本質上是一個id為鍵的字典。 或反之亦然name
  4. 在使用pandas時更改索引,然后更改它們,轉置,子集等是非常常見的(通常非常快),因此通常沒有必要在開始時過多地考慮結構。 只需根據需要隨時更改即可。
  5. 這可能是在切線上下降,但是上面提到的比較簡單的熊貓可能是Series而不是數據DataFrame 系列本質上是數據幀的一列,盡管它實際上只是一個帶索引(“keys”)的一維數據數組。

快速演示(使用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

詞典列表的第一個選項會好得多,原因很少。 List確實提供了諸如EXTEND,APPENT,PUSH之類的方法,這些方法不適用於詞典。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM