Cách hiệu quả nhất để tạo một từ điển của hai cột Dataframe gấu trúc là gì?


136

Cách hiệu quả nhất để tổ chức Dataframe sau đây là gì:

dữ liệu =

Position    Letter
1           a
2           b
3           c
4           d
5           e

vào từ điển như thế alphabet[1 : 'a', 2 : 'b', 3 : 'c', 4 : 'd', 5 : 'e']nào?

Câu trả lời:


182
In [9]: pd.Series(df.Letter.values,index=df.Position).to_dict()
Out[9]: {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e'}

So sánh tốc độ (sử dụng phương pháp của Wouter)

In [6]: df = pd.DataFrame(randint(0,10,10000).reshape(5000,2),columns=list('AB'))

In [7]: %timeit dict(zip(df.A,df.B))
1000 loops, best of 3: 1.27 ms per loop

In [8]: %timeit pd.Series(df.A.values,index=df.B).to_dict()
1000 loops, best of 3: 987 us per loop

20
Không tạo Sê-ri trước ... dict (zip (df.Pocation, df.Letter))
Wouter Overmeire

1
FYI ..... phương pháp của tôi rất gần với mui xe như những gì Wouter đang làm, sự khác biệt được thực hiện bằng cách sử dụng izip, hơn là zip; máy phát điện tạo ra sự khác biệt tôi đoán
Jeff

1
@WouterOvermeire điều này hoạt động hoàn hảo trong ứng dụng của tôi, cảm ơn bạn vì sự đóng góp của bạn
1083734

3
@Jeff dict (zip ...) nhanh nhất
Wouter Overmeire

3
Trên DataFrame có hình dạng = (100,2), phương thức của Wouter với dict (zip ...) nhanh hơn gấp 3 lần so với Jeff - Tôi đã sử dụng% timeit
Quetzalcoatl

79

Tôi đã tìm thấy một cách nhanh hơn để giải quyết vấn đề, ít nhất là trên các bộ dữ liệu thực tế lớn bằng cách sử dụng: df.set_index(KEY).to_dict()[VALUE]

Bằng chứng trên 50.000 hàng:

df = pd.DataFrame(np.random.randint(32, 120, 100000).reshape(50000,2),columns=list('AB'))
df['A'] = df['A'].apply(chr)

%timeit dict(zip(df.A,df.B))
%timeit pd.Series(df.A.values,index=df.B).to_dict()
%timeit df.set_index('A').to_dict()['B']

Đầu ra:

100 loops, best of 3: 7.04 ms per loop  # WouterOvermeire
100 loops, best of 3: 9.83 ms per loop  # Jeff
100 loops, best of 3: 4.28 ms per loop  # Kikohs (me)

18
Luôn luôn cuộn xuống để có thể trả lời nhanh hơn!
Sói Nour

5

Trong Python 3.6, cách nhanh nhất vẫn là WouterOvermeire. Đề xuất của Kikohs chậm hơn hai lựa chọn còn lại.

import timeit

setup = '''
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randint(32, 120, 100000).reshape(50000,2),columns=list('AB'))
df['A'] = df['A'].apply(chr)
'''

timeit.Timer('dict(zip(df.A,df.B))', setup=setup).repeat(7,500)
timeit.Timer('pd.Series(df.A.values,index=df.B).to_dict()', setup=setup).repeat(7,500)
timeit.Timer('df.set_index("A").to_dict()["B"]', setup=setup).repeat(7,500)

Các kết quả:

1.1214002349999777 s  # WouterOvermeire
1.1922008498571748 s  # Jeff
1.7034366211428602 s  # Kikohs

4

TL; DR

>>> import pandas as pd
>>> df = pd.DataFrame({'Position':[1,2,3,4,5], 'Letter':['a', 'b', 'c', 'd', 'e']})
>>> dict(sorted(df.values.tolist())) # Sort of sorted... 
{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
>>> from collections import OrderedDict
>>> OrderedDict(df.values.tolist())
OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)])

Trong dài

Giải thích về giải pháp: dict(sorted(df.values.tolist()))

Được:

df = pd.DataFrame({'Position':[1,2,3,4,5], 'Letter':['a', 'b', 'c', 'd', 'e']})

[ngoài]:

 Letter Position
0   a   1
1   b   2
2   c   3
3   d   4
4   e   5

Thử:

# Get the values out to a 2-D numpy array, 
df.values

[ngoài]:

array([['a', 1],
       ['b', 2],
       ['c', 3],
       ['d', 4],
       ['e', 5]], dtype=object)

Sau đó, tùy chọn:

# Dump it into a list so that you can sort it using `sorted()`
sorted(df.values.tolist()) # Sort by key

Hoặc là:

# Sort by value:
from operator import itemgetter
sorted(df.values.tolist(), key=itemgetter(1))

[ngoài]:

[['a', 1], ['b', 2], ['c', 3], ['d', 4], ['e', 5]]

Cuối cùng, bỏ danh sách danh sách 2 thành phần thành một lệnh.

dict(sorted(df.values.tolist())) 

[ngoài]:

{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}

Liên quan

Trả lời bình luận @sbradbio:

Nếu có nhiều giá trị cho một khóa cụ thể và bạn muốn giữ tất cả chúng, đó không phải là cách hiệu quả nhất nhưng trực quan nhất là:

from collections import defaultdict
import pandas as pd

multivalue_dict = defaultdict(list)

df = pd.DataFrame({'Position':[1,2,4,4,4], 'Letter':['a', 'b', 'd', 'e', 'f']})

for idx,row in df.iterrows():
    multivalue_dict[row['Position']].append(row['Letter'])

[ngoài]:

>>> print(multivalue_dict)
defaultdict(list, {1: ['a'], 2: ['b'], 4: ['d', 'e', 'f']})

Có cách nào bạn có thể thêm nhiều hơn một cột làm giá trị{'key': [value1, value2]}
sbradbio

1
Kiểm tra câu trả lời được nối thêm
alvas

Tôi nghĩ value1 và value2 là hai cột riêng biệt. Bạn có thể tạo một từ điển với {'id': ['long', 'lat]} không? dài và lat là trong các cột riêng biệt.
km
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.