2015-05-29 45 views
29

Tôi đang làm một số bài tập với bộ dữ liệu như vậy:Danh sách với nhiều từ điển Từ điển VS với vài danh sách?

Danh sách với nhiều từ điển

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

điển với vài danh sách

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

Pandas dataframes

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

Câu hỏi:

  1. Tôi có nên cấu trúc bộ dữ liệu như người sử dụng hoặc như users2?
  2. Có sự khác biệt về hiệu suất không?
  3. Có thể đọc dễ hơn cái kia không?
  4. Có tiêu chuẩn nào tôi nên tuân thủ không?
  5. Tôi thường chuyển đổi chúng thành các khung dữ liệu gấu trúc. Khi tôi làm điều đó, cả hai phiên bản đều giống nhau ... đúng không?
  6. Kết quả là đúng đối với mỗi phần tử vì vậy không quan trọng nếu tôi làm việc với quyền của gấu trúc df phải không?
+5

câu hỏi đẹp tôi sẽ đi với các tùy chọn đầu tiên vì tôi Recon tìm kiếm và chèn sẽ ít tẻ nhạt so với thứ hai – therealprashant

+4

Tôi sẽ đi với cái đầu tiên miễn là thuận tiện sử dụng là khía cạnh quan trọng nhất. Việc có ID cùng với NAME sẽ hữu ích khi di chuyển mọi thứ xung quanh. –

+3

Phiên bản đầu tiên có thể dễ dàng sắp xếp ở vị trí thứ hai. –

Trả lời

24

này liên quan đến column oriented databases so với hàng theo định hướng. Ví dụ đầu tiên của bạn là cấu trúc dữ liệu theo hàng và thứ hai là cột được định hướng. Trong trường hợp cụ thể của Python, đầu tiên có thể được thực hiện đáng kể hiệu quả hơn bằng cách sử dụng slots, sao cho từ điển của các cột không cần phải được nhân đôi cho mỗi hàng.

Biểu mẫu nào hoạt động tốt hơn phụ thuộc rất nhiều vào những gì bạn làm với dữ liệu; ví dụ, hàng định hướng là tự nhiên nếu bạn chỉ bao giờ truy cập tất cả các hàng. Cột định hướng trong khi đó làm cho việc sử dụng bộ nhớ cache tốt hơn và như vậy khi bạn đang tìm kiếm theo một trường cụ thể (bằng Python, điều này có thể bị giảm do sử dụng nhiều tài liệu tham khảo; các kiểu như array có thể tối ưu hóa). Cơ sở dữ liệu định hướng hàng truyền thống thường sử dụng các chỉ mục được sắp xếp theo cột để tăng tốc độ tìm kiếm và biết các kỹ thuật này bạn có thể triển khai bất kỳ kết hợp nào bằng cách sử dụng kho khóa-giá trị.

Pandas chuyển đổi cả hai ví dụ của bạn sang cùng một định dạng, nhưng bản thân chuyển đổi thì đắt hơn cho cấu trúc định hướng hàng, đơn giản vì mỗi từ điển riêng lẻ phải được đọc. Tất cả các chi phí này có thể là biên.

Có một lựa chọn thứ ba không hiển nhiên trong ví dụ của bạn: Trong trường hợp này, bạn chỉ có hai cột, một trong số đó là một số nguyên trong một phạm vi liền kề từ 0. Điều này có thể được lưu trữ theo thứ tự của các mục, nghĩa là toàn bộ cấu trúc sẽ được tìm thấy trong danh sách bạn đã gọi là users2['name']; nhưng đáng chú ý là các mục nhập không đầy đủ nếu không có vị trí của chúng. Danh sách dịch thành các hàng bằng cách sử dụng liệt kê(). Một cơ sở dữ liệu cũng thường gặp trường hợp đặc biệt này (ví dụ, sqlite rowid).

Nói chung, hãy bắt đầu với cấu trúc dữ liệu giúp mã của bạn trở nên hợp lý và chỉ tối ưu hóa khi bạn biết các trường hợp sử dụng của mình và có vấn đề về hiệu suất có thể đo lường. Các công cụ như Pandas có thể có nghĩa là hầu hết các dự án sẽ hoạt động tốt mà không cần finetuning.

+0

Ví dụ về cách sử dụng 'vị trí' để tiết kiệm bộ nhớ: http://tech.oyster.com/save-ram-with-python-slots/ –

4

users nói chung thực sự là tập hợp các yếu tố user. Vì vậy, tốt hơn là xác định phần tử user là một thực thể độc lập. Vì vậy, lựa chọn đầu tiên của bạn là đúng.

5

Thời gian phức tạp cho việc tra cứu trong -

  • sách thành viên - O (n)
  • dicts - O (1)

Nhưng điều đó sẽ không làm tổn thương nhiều nếu isn dữ liệu của bạn' Các bộ xử lý ngày nay lớn và hiện đại cũng khá hiệu quả.
Bạn nên sử dụng công cụ tìm kiếm trong đó việc tìm kiếm dễ dàng hơn và dễ đọc hơn (các vấn đề về khả năng đọc).
Tùy chọn đầu tiên là khá thích hợp vì biến là tập hợp người dùng (đã được gán id) trong khi biến thứ hai chỉ là tập hợp tên người dùng và id.

+1

"Bạn nên đi với một trong đó tra cứu là cú pháp sạch hơn và dễ đọc" +1. Nhưng tôi không nghĩ vấn đề phức tạp về thời gian vì chúng tôi không biết làm cách nào anh ta truy cập dữ liệu đó. –

6

Người dùng

  1. Khi bạn cần phải thêm một số người dùng mới chỉ tạo ra một mới dict của tất cả các chi tiết người dùng và thêm nó

  2. Dễ dàng sắp xếp được như @StevenRumbalski gợi ý

  3. Tìm kiếm sẽ dễ dàng

  4. này là nhỏ gọn hơn và dễ dàng kiểm soát được như kỷ lục tăng trưởng (đối với một số số lượng rất cao của các hồ sơ Tôi nghĩ chúng ta sẽ cần một cái gì đó tốt hơn so với người dùng quá)

Users2

  1. Cá nhân tôi nhìn thấy đây là lần đầu tiên và tôi sẽ không tiếp cận điều này nếu tôi có số lượng hồ sơ cao.

PS: Nhưng tôi muốn tìm hiểu lợi thế của users2 qua users Một lần nữa một câu hỏi đẹp

1

Tùy chọn đầu tiên trong danh sách từ điển sẽ tốt hơn nhiều vì một vài lý do. Danh sách cung cấp các phương thức như EXTEND, APPENT, PUSH không sẵn có với từ điển.

4

Một số câu trả lời liên quan đến các khía cạnh gấu trúc:

  1. Cả dataframes có thực sự giống nhau và là cột định hướng, đó là tốt, bởi vì gấu trúc hoạt động tốt nhất khi dữ liệu trong mỗi cột là đồng nhất (tức là con số có thể được lưu trữ như ints và phao). Một lý do chính cho việc sử dụng gấu trúc ở nơi đầu tiên là bạn có thể thực hiện các phép toán số hóa vectơ có độ lớn nhanh hơn python tinh khiết - nhưng điều này phụ thuộc vào tổ chức cột khi dữ liệu không đồng nhất.
  2. Bạn có thể làm pd_users.T để chuyển đổi, nếu bạn muốn, và sau đó sẽ thấy (qua info() hoặc dtypes) mọi thứ sau đó được lưu trữ như một đối tượng mục đích chung vì cột chứa cả chuỗi và số.
  3. Sau khi được chuyển đổi, bạn có thể làm pd_users.set_index('id') để khung dữ liệu của bạn về cơ bản là từ điển với id làm khóa. Hoặc ngược lại với name. Nó là khá phổ biến (và thường khá nhanh) để thay đổi chỉ mục, sau đó thay đổi chúng trở lại, chuyển đổi, tập hợp con, vv khi làm việc với gấu trúc vì vậy nó thường không cần thiết phải suy nghĩ quá nhiều về cấu trúc lúc đầu. Chỉ cần thay đổi nó khi bạn cần phải bay.
  4. Điều này có thể bị tắt trên đường tiếp tuyến, nhưng tương tự gấu trúc đơn giản hơn của những gì bạn có ở trên có thể là Series thay vì DataFrame. Một loạt về cơ bản là một cột của một khung dữ liệu mặc dù nó thực sự chỉ là một mảng dữ liệu một chiều với một chỉ mục ("chìa khóa").

bản demo nhanh (sử dụng df như tên dataframe, quy ước phổ biến):

>>> 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 
+0

Hey! Bạn đã đề cập rằng cả hai khung dữ liệu đều được định hướng cột. Câu trả lời được bỏ phiếu nhiều nhất hiện nay cho thấy một là cột và cột kia là hàng. Bạn có thể xác nhận? – megashigger

+1

Tôi tin rằng @YannVernier chỉ đề cập đến trường hợp * trước * chuyển đổi thành gấu trúc. Bạn đã chứng minh rằng họ là chính bạn với 'pd_users == pd_users2'. Nhưng bạn có thể làm 'pd_users == pd_users2.T' (đặt một transpose trên một trong hai) để xác minh thêm. Nó sẽ tăng một ngoại lệ vì hai datafram không còn phù hợp nữa. Ngoài việc kiểm tra bình đẳng, chỉ cần in khung dữ liệu cho thấy cách gấu trúc đang cấu trúc dữ liệu theo hàng và cột. – JohnE

+0

Ah ok có ý nghĩa. Cảm ơn bạn đã làm rõ. – megashigger

Các vấn đề liên quan