python pandas khung dữ liệu vào từ điển


111

Tôi có một khung dữ liệu hai cột và định chuyển nó thành từ điển python - cột đầu tiên sẽ là khóa và cột thứ hai sẽ là giá trị. Cảm ơn bạn trước.

Khung dữ liệu:

    id    value
0    0     10.2
1    1      5.7
2    2      7.4


bạn đã kiểm tra điều này chưa ?: pandas.pydata.org/pandas-docs/dev/generated/…
user2290820

4
@perigee: Bạn có thể chấp nhận một trong các câu trả lời (nếu hữu ích) để đánh dấu câu hỏi là đã giải quyết không? Điều này cũng sẽ giúp những người dùng khác.
MERose

nếu bạn có một id phù hợp với chỉ mục, bạn nên đặt nó làm chỉ mục.
Faris

Câu trả lời:


152

Xem tài liệu cho to_dict. Bạn có thể sử dụng nó như thế này:

df.set_index('id').to_dict()

Và nếu bạn chỉ có một cột, để tránh tên cột cũng là một cấp trong dict (thực tế, trong trường hợp này, bạn sử dụng Series.to_dict()):

df.set_index('id')['value'].to_dict()

14
Lưu ý rằng lệnh này sẽ bị mất dữ liệu nếu có giá trị dư thừa trong các cột ID: >>> ptest = p.DataFrame([['a',1],['a',2],['b',3]], columns=['id', 'value']) >>> ptest.set_index('id')['value'].to_dict()
dalloliogm

9
Tôi phải nói rằng, không có gì trong liên kết tài liệu đó có thể cho tôi câu trả lời cho câu hỏi này.
Ben Fulton

@bombayquant xem câu trả lời của DSM và của tôi bên dưới. Lưu ý rằng đây là một cuộc thảo luận 4 năm tuổi.
dalloliogm

66
mydict = dict(zip(df.id, df.value))

1
Lưu ý: trong trường hợp chỉ số là chìa khóa từ điển mong muốn, sau đó thực hiện: dict (zip (df.index, df.value))
aLbAc

47

Nếu bạn muốn một cách đơn giản để bảo vệ các bản sao, bạn có thể sử dụng groupby:

>>> ptest = pd.DataFrame([['a',1],['a',2],['b',3]], columns=['id', 'value']) 
>>> ptest
  id  value
0  a      1
1  a      2
2  b      3
>>> {k: g["value"].tolist() for k,g in ptest.groupby("id")}
{'a': [1, 2], 'b': [3]}

1
Giải pháp đẹp và thanh lịch, nhưng trên bảng 50k hàng, nó chậm hơn khoảng 6 lần so với giải pháp xấu xí của tôi bên dưới.
dalloliogm

@dalloliogm: bạn có thể đưa ra một bảng ví dụ xảy ra cho? Nếu nó chậm hơn sáu lần so với vòng lặp Python, có thể có lỗi hiệu suất ở gấu trúc.
DSM

23

Các câu trả lời bằng joris trong chuỗi này và bằng punchagan trong chuỗi sao chép rất thanh lịch, tuy nhiên chúng sẽ không cho kết quả chính xác nếu cột được sử dụng cho các khóa chứa bất kỳ giá trị trùng lặp nào.

Ví dụ:

>>> ptest = p.DataFrame([['a',1],['a',2],['b',3]], columns=['id', 'value']) 
>>> ptest
  id  value
0  a      1
1  a      2
2  b      3

# note that in both cases the association a->1 is lost:
>>> ptest.set_index('id')['value'].to_dict()
{'a': 2, 'b': 3}
>>> dict(zip(ptest.id, ptest.value))
{'a': 2, 'b': 3}

Nếu bạn có các mục nhập trùng lặp và không muốn mất chúng, bạn có thể sử dụng mã xấu xí nhưng hoạt động tốt này:

>>> mydict = {}
>>> for x in range(len(ptest)):
...     currentid = ptest.iloc[x,0]
...     currentvalue = ptest.iloc[x,1]
...     mydict.setdefault(currentid, [])
...     mydict[currentid].append(currentvalue)
>>> mydict
{'a': [1, 2], 'b': [3]}

2
Xin lỗi định dạng do thiếu khối trong nhận xét:mydict = defaultdict(list)\n for (key, val) in ptest[["id", "value"]].itertuples(index=False):\n mydict[key].append(val)
Midnighter

1
Mặc dù không trang nhã như một lớp lót, nhưng tôi thích giải pháp của bạn hơn nhiều.
Peter Maguire

9

Giải pháp đơn giản nhất:

df.set_index('id').T.to_dict('records')

Thí dụ:

df= pd.DataFrame([['a',1],['a',2],['b',3]], columns=['id','value'])
df.set_index('id').T.to_dict('records')

Nếu bạn có nhiều giá trị, như val1, val2, val3, v.v. và bạn muốn chúng dưới dạng danh sách, thì hãy sử dụng mã dưới đây:

df.set_index('id').T.to_dict('list')

1
những gì không recordscó nghĩa là ở đây?
mingchau

1
@mingchau recordsở đây có nghĩa là ‘records’ : list like [{column -> value}, … , {column -> value}] Xem pandas.pydata.org/pandas-docs/stable/reference/api/…
AmuletxHeart

8

trong một số phiên bản mã bên dưới có thể không hoạt động

mydict = dict(zip(df.id, df.value))

vì vậy hãy làm cho nó rõ ràng

id_=df.id.values
value=df.value.values
mydict=dict(zip(id_,value))

Lưu ý rằng tôi đã sử dụng id_ vì id từ là từ dành riêng


7

Bạn có thể sử dụng 'đọc hiểu chính tả'

my_dict = {row[0]: row[1] for row in df.values}

Looping với gấu trúc không phải là hiệu quả nhất về sử dụng bộ nhớ. Xem: engineering.upside.com/…
tda

OP đã không yêu cầu câu trả lời hiệu quả nhất nên tôi nghĩ @Dongwan Kim đã cung cấp giải pháp thay thế tốt.
Một nhà kinh tế học

3

Một giải pháp khác (ngắn hơn một chút) để không mất các mục nhập trùng lặp:

>>> ptest = pd.DataFrame([['a',1],['a',2],['b',3]], columns=['id','value'])
>>> ptest
  id  value
0  a      1
1  a      2
2  b      3

>>> pdict = dict()
>>> for i in ptest['id'].unique().tolist():
...     ptest_slice = ptest[ptest['id'] == i]
...     pdict[i] = ptest_slice['value'].tolist()
...

>>> pdict
{'b': [3], 'a': [1, 2]}

1

Bạn cần một danh sách làm giá trị từ điển. Mã này sẽ thực hiện thủ thuật.

from collections import defaultdict
mydict = defaultdict(list)
for k, v in zip(df.id.values,df.value.values):
    mydict[k].append(v)

1

Tôi đã tìm thấy câu hỏi này trong khi cố gắng tạo một từ điển từ ba cột của khung dữ liệu gấu trúc. Trong trường hợp của tôi, khung dữ liệu có các cột A, B và C (giả sử A và B là tọa độ địa lý của kinh độ và vĩ độ và C là vùng / tiểu bang / v.v. của quốc gia, ít nhiều là như vậy).

Tôi muốn có một từ điển với mỗi cặp giá trị A, B (khóa từ điển) khớp với giá trị của C (giá trị từ điển) trong hàng tương ứng (mỗi cặp giá trị A, B được đảm bảo là duy nhất do lọc trước đó, nhưng nó là có thể có cùng giá trị C cho các cặp giá trị A, B khác nhau trong ngữ cảnh này), vì vậy tôi đã làm:

mydict = dict(zip(zip(df['A'],df['B']), df['C']))

Sử dụng pandas to_dict () cũng hoạt động:

mydict = df.set_index(['A','B']).to_dict(orient='dict')['C']

(không có cột A hoặc B nào được sử dụng làm chỉ mục trước khi thực hiện dòng tạo từ điển)

Cả hai cách tiếp cận đều nhanh (chưa đầy một giây trên khung dữ liệu với 85 nghìn hàng, máy tính xách tay lõi kép nhanh 5 năm tuổi).

Lý do tôi đăng bài này:

  1. cho những người cần loại giải pháp này
  2. nếu ai đó biết một giải pháp thực thi nhanh hơn (ví dụ: cho hàng triệu hàng), tôi sẽ đánh giá cao câu trả lời.

0
def get_dict_from_pd(df, key_col, row_col):
    result = dict()
    for i in set(df[key_col].values):
        is_i = df[key_col] == i
        result[i] = list(df[is_i][row_col].values)
    return result

đây là sự lười biếng của tôi, một vòng lặp cơ bản


0

Đây là giải pháp của tôi:

import pandas as pd
df = pd.read_excel('dic.xlsx')
df_T = df.set_index('id').T
dic = df_T.to_dict('records')
print(dic)
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.